Lately, to be more precise starting from April 10th, I started working at BBC. Wonderful environment, very nice people, so everything is perfect. They work with Java and other technologies (Apache Camel is one of the library they use, I could write about it one day, when I will be more proficient). I am a bit rusty on Java, I coded for a very long time with this language, but ehy, details are details, so sometimes you forgot them.

Visibility is a very complicated matter, especially if you want to be REALLY sure that nobody can mess with your classes. All the tests I will speak about are written, compiled and reported from this online JAVA IDE that I found very useful for making fast tests. I hope everyone is aware of visibility in general. Anyway it can be useful to remember the 4 type of visibility: let’s say that we have four classes, the first two (Alpha and Beta) in one package, the second two (AlphaSub that extends Alpha, and Omega) in a different package. The visibility of members of Alpha is the following one:

Visibility
Modifier Alpha Beta Alphasub Gamma
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N

Let’s speak about instances: the object of the specific classes doesn’t really care about being objects. This means that objects of Alpha can see private members of other objects of Alpha. I give an example…

  1. public class HelloWorld
  2. {
  3.   public static void main(String[] args)
  4.   {
  5.     ClassA a = new ClassA("First object");
  6.     ClassB b = new ClassB("Second object");
  7.     ClassA c = new ClassA("Third object");
  8.     a.read(a);
  9.     a.read(b);
  10.     a.read(c);
  11.     b.read(c);
  12.   }
  13. }
  14.  
  15. interface ParentClass
  16. {
  17.   public void read(ParentClass pc);
  18. }
  19.  
  20. public class ClassA implements ParentClass
  21. {
  22.   private String message;
  23.   public ClassA(String input)
  24.   {
  25.     message = "Class A: " + input;
  26.   }
  27.   public void read(ParentClass pc){
  28.     if(pc instanceof ClassA) System.out.println(((ClassA)pc).message);
  29.     else pc.read(pc);
  30.   }
  31. }
  32.  
  33. public class ClassB implements ParentClass
  34. {
  35.   private String message;
  36.   public ClassB(String input)
  37.   {
  38.     message = "Class B: " + input;
  39.   }
  40.   public void read(ParentClass pc){
  41.     if(pc instanceof ClassB) System.out.println(((ClassB)pc).message);
  42.     else pc.read(pc);
  43.   }
  44. }

This is valid, even when object a accesses a private member of object c, its message. But this is still normal, the other thing I would like you to think is what happens with inner classes. I give you an example with the following code:

  1. public class HelloWorld
  2. {
  3.   public static void main(String[] args)
  4.   {
  5.     ClassA a = new ClassA("First object");
  6.     System.out.println(a.getB("creating second object").getMsg());
  7.     System.out.println(a.new ClassB("test").getMsg());
  8.     ClassA.ClassB c = a.new ClassB("test2");
  9.     a = null;
  10.     System.gc();
  11.     System.out.println(c.getMsg());
  12.   }
  13. }
  14.  
  15. public class ClassA
  16. {
  17.   private String message;
  18.   public ClassA(String input)
  19.   {
  20.     message = "Class A: " + input;
  21.   }
  22.   public ClassB getB(String msg){
  23.     return new ClassB("From "+message+": "+msg);
  24.   }
  25.  
  26.   class ClassB {
  27.     private String messageB;
  28.     ClassB(String mess){
  29.       messageB = "ClassB: " + mess;
  30.     }
  31.     public String getMsg() { return messageB; }
  32.   }
  33. }

Again, nothing exceptional even if… the use of new as a method of a is perfectly valid, meaning that if you try to create a ClassA.ClassB object alone the compiler complains about an instance of ClassB not referenced by an instance of ClassA, but if you use an instance of ClassA just to create an instance of ClassB and then you remove and clean it’s class, everything is fine.

Last but not least, I was discussing about lazy initialization of thread-safe Singletons in Java. I think everyone knows how to write a normal singleton in Java. I leave you this design pattern to think about cause I found it clean and interesting.

  1. public class HelloWorld
  2. {
  3.   public static void main(String[] args)
  4.   {
  5.     System.out.println("Initializing - here you can do whatever you want, ClassA will be created lazily");
  6.     ClassA a = null;
  7.     a = ClassA.getInstance();
  8.   }
  9. }
  10.  
  11. public class ClassA
  12. {
  13.   private String message;
  14.   private static class Holder {
  15.     private static ClassA instance = new ClassA("Holder");
  16.   }
  17.  
  18.   private ClassA(String message){
  19.     System.out.println("Constructor of class A");
  20.     this.message = message;
  21.   }
  22.  
  23.   public static ClassA getInstance() {
  24.     System.out.println("Invoked getInstance");
  25.     return Holder.instance;
  26.   }
  27.  
  28.   public String getMessage() { return message; }
  29. }

All the trick is based on the way in which JVM works. A class should be referenced in the code to force JVM to load it. And JVM loads it ONCE, being intrinsically thread safe. So the output of the above code is the following:

Initializing – here you can do whatever you want, ClassA will be created lazily
Invoked getInstance
Constructor of class A

But what is we remove the Holder class? Basically the instance will be created when the entire ClassA will be loaded, and this, for sure, will happen BEFORE you can invoke the getInstance. Meaning that the lazy initialization now is moved when you create the object of ClassA, not when you invoke the getInstance. The output is:

Initializing – here you can do whatever you want, ClassA will be created lazily
Constructor of class A
Invoked getInstance

For today it is enough.
Stay tuned!

Share