When should i create inner class or inner static class? - java

I am aware about the static keyword, but in short. My attempt is to create inner static class since it's related to outer class. The practical problem is I am confused how to access it. My reason use static class is that I just need one instance of it per application?
Please correct if you found any misconseption, and give real usage of the class / static class.
public class DbPredecessorTest {
List<Book> db;
Book book;
Integer numberOfBooks;
static BufferedReader reader;
static {
try {
reader = new BufferedReader(new FileReader(Main.fileLoc));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
static class Helper {
DbPredecessor dbPredecessor= new DbPredecessor();
Long getLines() {
return reader.lines().count();
}
}
My directionless attempt:
class SomeTest {
#Test
void ableToSave() throws IOException {
db.add(book);
boolean save = Helper.dbPredecessor.save(db);
assertEquals(true, save);
}
#Test
void save_should_increaseLine() throws IOException {
db.add(book);
// numberOfBooks= (int) Helper.get
boolean save = dbPredecessor.save(db);
assertEquals(numberOfBooks+1, reader.lines().count());
}
}

That's not the reason to use a static inner class. A static inner class is functionally an ordinary Java class, the only real reason you would have one is to indicate it's related to the outer class in some way or to make it private.
You could just use a normal static method here:
public class DbPredecessorTest {
static long getLines() {
return reader.lines().count();
}
}
and then use it like so:
long numberOfBooks = DbPredecessorTest.getLines();

Related

How to save static variable when I serialize

My Goal: I need to keep the App state exactly in same sate after shutdown, lets say it's equivalent to "suspend" state.
My Problem : I do know that serialization mechanism doesn't save transient variables neither static variables. However I need to maintain the static variables in exactly same state after App suspension/shut down.
Approach-1 : I could save the state of static variable(s) into a different file, using my "file format", and serialize the objects into a different one.
a) Is this the "normal" approach?
Approach-2 : If I extend the ObjectInputStream/ObjectOutputStreamand override the methods readStreamHeader/writeStreamHeaderI can write whatever I want. So I can also write my static variables.
b) Am I doing something I should not?
Here's the code I've written testing approach-2, and seams to work fine. Please note, I'm not a Java programmer, so for it's very important to understand best practices, if there's any in this particular case.
#SuppressWarnings("serial")
class SequenceIdentifier implements Serializable
{
protected static long seqIdentifier_ = 1L; //This variable MUST NOT be reseted.
private long id_; //Object variable to be serialised.
private SequenceIdentifier(long id)
{ id_ = id;
}
#Override
public String toString()
{ return ("Id : " + id_ + " of " + seqIdentifier_);
}
public static SequenceIdentifier newInstance()
{ return new SequenceIdentifier(seqIdentifier_++);
}
}
final class OOStream extends ObjectOutputStream
{
public OOStream(OutputStream out) throws IOException
{ super(out);
}
#Override
protected void writeStreamHeader() throws IOException
{ super.writeLong(SequenceIdentifier.seqIdentifier_);
}
}
final class OIStream extends ObjectInputStream
{
public OIStream(InputStream in) throws IOException
{ super(in);
}
#Override
protected void readStreamHeader() throws IOException
{ SequenceIdentifier.seqIdentifier_ = super.readLong();
}
}
public class Main
{
public static void dump(ArrayList<SequenceIdentifier> ids)
{
for (SequenceIdentifier id : ids)
System.out.println(id);
}
public static void saveData()
{
ArrayList<SequenceIdentifier> ids = new ArrayList<>(Arrays.asList(SequenceIdentifier.newInstance(),
SequenceIdentifier.newInstance(),
SequenceIdentifier.newInstance(),
SequenceIdentifier.newInstance()));
try (OOStream oOut = new OOStream(new FileOutputStream("foo.bin")))
{ oOut.writeObject(ids);
} catch (Exception e)
{ System.err.println(e);
}
dump(ids);
}
#SuppressWarnings("unchecked")
public static void loadData()
{
ArrayList<SequenceIdentifier> ids = null;
try (OIStream oIn = new OIStream(new FileInputStream("foo.bin")))
{ ids = (ArrayList<SequenceIdentifier>)oIn.readObject();
} catch (Exception e)
{ System.err.println(e);
}
dump(ids);
}
public static void main(String[] args)
{
saveData();
System.out.println("Counter at this point " + SequenceIdentifier.seqIdentifier_);
SequenceIdentifier.seqIdentifier_ = 0;
loadData();
System.out.println("Counter at this point " + SequenceIdentifier.seqIdentifier_);
}
}
I would create a separate Memento-class containing all the relevant data as fields and de-/serialize that.
class MyClassWithStaticFields1 {
private static String field;
}
class MyClassWithStaticFields2 {
private static String field;
}
class StaticMemento {
String field1;
String field2;
}
// serialization
StaticMemento mem = new StaticMemento();
mem.field1 = MyClassWithStaticFields1.field;
mem.field2 = MyClassWithStaticFields2.field;
outputStream.writeObject(mem);
// deserialize
StaticMemento mem = outputStream.readObject();
MyClassWithStaticFields1.setField(mem.field1);
MyClassWithStaticFields2.setField(mem.field2);
So basically your Approach-1.
Several possibilities.
Make it non-static.
Write complementary readObect()/writeObject() methods that call defaultReadObject() and defaultWriteObject() respectively and then serialize/deserialize the field.
Write complementary writeReplace()/readResolve() methods that substitute a proxy object that does contain this member as a non-transient non-static member.
Make the object Externalizable and take complete control of the serialization process yourself in the associated methods.
Review your requirement.

Mocking a DAO in Mockito

I'm just getting into testing of code. I have done unit tests before but haven't really isolated them. So they were more like integration test (indirectly). I want to give Mockito a try and I have added it to my Intellij IDE.
But I have no idea of how to actually implement mocking at all. There are examples on their website but I just can't wrap my head around the concept of mocking. I know that one uses mocking to isolate the unit testing to ensure that the errors are in the unit itself and not in a dependency.
I wrote the following:
#Test
public void testChangeMemberReturnsTrue() throws Exception {
Member tempMem = new Member();
tempMem.setMemberFirstName("Swagrid");
tempMem.setMemberLastName("McLovin");
tempMem.setMemberID("SM666");
SQLDUMMY.saveMember(tempMem); //Save member to dummy DB.
Member checkMem = new Member();
ArrayList<Member> memArr = SQLDUMMY.getAllMembers();
for (Member m : memArr) { // Look through all saved members
if (m.equals(tempMem)) { // If match, save to checkMem
checkMem = m;
}
}
assertTrue(tempMem.equals(checkMem)); // Make sure they are really equal.
String newfirstname = "Darius";
String newlastname = "DunkMaster";
assertTrue(memhandling.changeMember(tempMem, newfirstname, newlastname));
}
And here is the actual method:
public boolean changeMember(Member mem, String n1, String n2) {
try {
ArrayList<Member> memArr = SQLDUMMY.getAllMembers();
for (Member m : memArr) {
if (m.equals(mem)) {
m.setMemberFirstName(n1);
m.setMemberLastName(n2);
m.setMemberID(ensureUniqueID(m, m.getMemberID())); //Just a method call to another method in the same class to ensure ID uniqueness.
return true;
}
else {
return false;
}
}
}
catch (Exception e) {
System.out.println("Error4.");
}
return false;
}
I'd like to mock the SQLDUMMY (Which I created just to see if my tests would pass at all, which they do.) The SQLDUMMY class looks like this:
public class SQLDUMMY {
private static ArrayList<Member> memberList = new ArrayList<>();
private static ArrayList<Ship> shipList = new ArrayList<>();
public static ArrayList<Member> getAllMembers() {
return memberList;
}
public static void saveMember(Member m) {
memberList.add(m);
}
public static void deleteMember(Member memIn) {
memberList.remove(memIn);
}
public static void saveShip(Ship newShip) {
shipList.add(newShip);
}
public static ArrayList<Ship> getAllShips() {
return shipList;
}
public static void deleteShip(Ship s) {
shipList.remove(s);
}
}
It basically just consists of getters and add/remove for the ArrayLists that act as a contemporary DB storage.
Summary: How can I mock the SQLDUMMY class (DAO), so it is no longer a dependency for the Unit tests?
You need to read on how Mockito works.
The basic idea is that it extends you class and and overrides all methods and allows you to return what ever you want it too.
Syntax is :
SQLDummy sqlDummy = Mockito.mock(SQLDummy.class);
Mockito.when(sqlDummy.getAllShips()).thenReturn(new ArrayList< Ship >())

How to make an interface object Java

For my CS class I am required to use some premade code and use the interface in my spreadsheet. I have a few classes already, Program, SpreadSheet, PersistanceHelper and an interface Savable.
package persistence;
public interface Savable {
public String[] getSaveData();
public void loadFrom(String[] saveData);
}
package persistence;
import java.io.*;
import java.util.*;
public class PersistenceHelper {
public static void save(String filePath, Savable toSave) throws Exception {
String[] data = toSave.getSaveData();
PrintStream out = new PrintStream(new File(filePath));
try {
for (String datum : data) {
out.println(datum);
}
} finally {
out.close();
}
}
public static void load(String filePath, Savable toLoadTo) throws Exception {
ArrayList<String> data = new ArrayList<String>();
Scanner input = new Scanner(new File(filePath));
try {
while (input.hasNextLine()) {
data.add(input.nextLine());
}
} finally {
input.close();
}
String[] dataArray = new String[data.size()];
toLoadTo.loadFrom(data.toArray(dataArray));
}
}
//These are this class and interface I am not allowed to change and I am required to use the save and load methods in the PersistanceHelper and am struggling to create a variable of the Savable type.
An interface simply describes how a class behaves externally. To get an instance, it must know how to retrieve results from declared functions, specified by the implementation:
public class MySavable implements Savable {
public String[] getSaveData() {
// some code
return whatever;
}
public void loadFrom(String[] saveData) {
// some code
}
}
You can then do things like:
Savable s = new MySavable();
String[] strings = s.getSaveData();
s.loadFrom(strings);
Implement the savable interface class , by child class say savableImpl. And that object you use with this interface.
Isn't it whole point of having interface.
public class SavableImpl implements Savable{
public String[] getSaveData(){
// implementation goes here
}
public void loadFrom(String[] saveData){
// implementation here
}
}
Then you can go like this :-
Savable savable = new SavableImpl();
I am pretty sure, whoever designed existing class , meant same to be done .

Generic static factory

I am getting a compilation error. I want my static method here to return a factory that creates and return Event<T> object. How can I fix this?
import com.lmax.disruptor.EventFactory;
public final class Event<T> {
private T event;
public T getEvent() {
return event;
}
public void setEvent(final T event) {
this.event = event;
}
public final static EventFactory<Event<T>> EVENT_FACTORY = new EventFactory<Event<T>>() {
public Event<T> newInstance() {
return new Event<T>();
}
};
}
Generic parameters of a class do not apply to static members.
The obvious solution is to use a method rather than a variable.
public static <U> EventFactory<Event<U>> factory() {
return new EventFactory<Event<U>>() {
public Event<U> newInstance() {
return new Event<U>();
}
};
}
The syntax is more concise in the current version of Java.
It is possible to use a the same instance of EventFactory stored in a static field, but that requires an unsafe cast.
You have:
public final class Event<T> {
...
public final static EventFactory<Event<T>> EVENT_FACTORY = ...
}
You cannot do this. T is a type that is associated with a specific instance of an Event<T>, and you cannot use it in a static context.
It's hard to give you good alternate options without knowing more about what exactly you are trying to do, as this is sort of an odd-looking factory implementation. I suppose you could do something like (put it in a method instead):
public final class Event<T> {
...
public static <U> EventFactory<Event<U>> createEventFactory () {
return new EventFactory<Event<U>>() {
public Event<U> newInstance() {
return new Event<U>();
}
};
};
}
And invoke it like:
EventFactory<Event<Integer>> factory = Event.<Integer>createEventFactory();
Or, if you don't want to be explicit (you don't really need to be, here):
EventFactory<Event<Integer>> factory = Event.createEventFactory();
Why don't you get rid of the whole static member of Event thing and either keep the factories separate, e.g.:
public final class GenericEventFactory<T> extends EventFactory<Event<T>> {
#Override public Event<T> newInstance() {
return new Event<T>();
}
}
And use, e.g., new GenericEventFactory<Integer>() where appropriate?

Strange Java error placement

Still working on the same project (Java-based shell) and tried to run it - and got a strange error. I was working with a single class that represents one of the commands, and, because of the fact that school computers have no compilers, I use ideone. Anyway, I am getting an error and, while I have seen it before, the placement is really weird. The error:
Main.java:56: error: no enclosing instance of type LIST_Command is in scope
public FAKE_CMD(int i) {this.msg = i;System.out.println(i);}
^
Shouldn't this be in a place that is CALLING the constructor, or a static method of the class?
And here is the code (in its entirety, let me know what I should trim or edit it out yourself) Yes, this makes it an SSCCE.
package javashell.ver2.command;
import java.io.*;
import java.util.*;
class LIST_Command { /*extends Command*/
public static Map<String, Command> commands = new HashMap<>();
public String description() {
return "List all commands, their descriptions, or usages.";
}
public String usage() {
return "list <cmds | desc | usage>";
}
public boolean runCmd(String[] cmdArgs, PrintStream output) {
try {
if (cmdArgs.length == 0) {
return false;
}
else if (cmdArgs.length > 0) {
if (cmdArgs[0].equals("cmds")) {
for (Map.Entry<String, Command> cmd : /*main.Main.*/commands.entrySet()) {
output.println(cmd.getKey());
}
}
else if (cmdArgs[0].equals("desc")) {
for (Map.Entry<String, Command> cmd : /*main.Main.*/commands.entrySet()) {
output.println(cmd.getValue().description());
}
}
}
return true;
}
catch (Exception e) {
return false;
}
}
public static void main(String[] args) {
commands.put("test1", new FAKE_CMD(1));
commands.put("test2", new FAKE_CMD(2));
new LIST_Command().runCmd(new String[] {"cmds"}, System.out);
}
abstract class Command {
public abstract String usage();
public abstract String description();
public abstract boolean runCmd(String[] cmdArgs, PrintStream output);
}
static class FAKE_CMD extends Command {
int msg;
public FAKE_CMD(int i) {
this.msg = i;
System.out.println(i);
}
public String usage() {
return "usagetest" + msg;
}
public String description() {
return "descriptiontest" + msg;
}
public boolean runCmd(String[] cmdArgs, PrintStream output) {
return true;
}
}
}
Command is an inner class, which doesn't seem to make sense since it is contained in a class that should be its subclass. Anyway, that is the cause of your error: regardless of whether FAKE_CMD is itself static or not, it needs an enclosing instance of LIST_Command since it extends Command.
Note a possible subtlety in Java's terminology: inner class means a non-static nested class, therefore it implies the need for an enclosing instance.
The constructor of FAKE_CMD need to call its superclass' (Command's) constructor. However, since the superclass is not static, Java has no way of instantiate a superclass instance before constructing a FAKE_CMD.

Categories

Resources