Consider the following program:
SomeClass.java:
package somepackage;
import java.util.List;
public class SomeClass implements SomeInterface {
public SomeClass(boolean add){}
public static void main(String[] args){
SomeSubclass sub1 = new SomeSubclass(false);
for (String s : sub1.getList())
System.out.println("before: " + s);
SomeSubclass sub2 = new SomeSubclass(true);
for (String s : sub1.getList())
System.out.println("after: " + s);
}
@Override
public void addToList(String s) {
someList.add(s);
}
@Override
public List<String> getList() {
return someList;
}
}
SomeSubclass.java:
package somepackage;
public class SomeSubclass extends SomeClass {
public SomeSubclass(boolean add){
super(add);
if (add)
this.addToList("a");
}
}
SomeInterface.java:
package somepackage;
import java.util.ArrayList;
import java.util.List;
public interface SomeInterface {
List<String> someList = new ArrayList<String>();
public void addToList(String s);
public List<String> getList();
}
The program, when run, outputs the following:
after: a
The first debug message is not sent, because the list of the first instance of SomeSubclass is empty. However, once an element is added to the list of the second instance, the first instance also has the element added. This occurs when compiled and run with JDK 1.8 and Java SE 8, respectively. From what I understand, it shouldn't be happening. Is it intentional, and if so, what is the proper way of accomplishing this task?
I also feel as though I should mention the practical implementation of this simplified code. An API I'm maintaining has a class in it which implements an interface called Metadatable, which stores a map of metadata of its instances. This class in recent snapshots may be overridden by the program using the API via a method, and when this is done, metadata effectively becomes static. Needless to say, this breaks the entire metadata portion of the API when it happens.