So I did read the tread of what and when static initalizer is executed from this thread. Static initializer in Java. But I am running into some old code written by someone else and can't seem to understand why he would use it the way he did.
My Class:
public class ClassA extends Thread {
.... private vars ....
private static Config config;
static {
config = null;
}
public ClassA(Config config) {
ClassA.config = config;
}
}
Why didn't he just do this?
public class ClassA extends Thread {
.... private vars ....
private static Config config = null;
public ClassA(Config config) {
ClassA.config = config;
}
}
I understand that static initalizer gets call as the class being redenered, so it sets config => null, while if i don't use static initalizer, instance variables get initalizer right before the constructor, and right after super. So wouldn't the two class be doing the same thing?
These classes are doing the same thing, but more complex static initializers can't always be done on a single line.
The static initializer in your first example won't have any effect on the behavior of that class. You could remove it entirely and nothing would change.
Why did I write x = x + 1 instead of x++ ? No particular reason, I just did it that way. I think it's the same here, because the 2 are basically identical and it doesn't really matter. On the other hand, if more complicated initialization is desired sometime in the future, maybe he can't do that in that single line of code.
The static block will initialize config only once when class is loaded, no matter how many instances of ClassA there are.
It doesn't matter which solution, it's just a technicality, I've seen people use both.
Both are doing exactly the same thing, It a matter of design choice.
Related
EDIT: Adding more context and code here:
Currently this is what I have:
public class MyClass{
private static MyClass2 mySharedObject = null; //this is the object that I want to share across m
private SomeRandomClass someRandomClass;
public MyClass(MyClass3 object3, MyClass4 object4, SomeRandomClass someRandomClass){
/* it just so happens that it is guaranteed that someRandomClass, no
matter which thread creates it, will have the same value. But the value is not known in design time and hence I can't move this initialize code to the static {} block, as suggested by many folks. One thing that I can do is move the creation of this sharedObject outside MyClass and do it before any threads actually use it. Unfortunately, I am dealing with a legacy code here and didn't want to do that change and that's why asked if the approach I presented is good enough or there is something better? */
this.someRandomClass = someRandomClass;
synchronized(mySharedObject){
if(mySharedObject ! =null){
mySharedObject = new MyClass2(someRandomClass);//It doesn't matter which thread wins to create this object. I just need a valid instance of someRandomClass to create mySharedObject. Once it is created, I can use it for all the threads.
}
}
}
}
Is there a better way?
PS: I don't want to pass this shared object in the constructor of MyClass and/or I don't want to make MyClass2 as singleton.
Thanks
Use a static initializer block.
public class MyClass {
private static MyClass2 mySharedObject;
static {
mySharedObject = null; // whatever value here
}
// The rest of MyClass
}
EDIT: From your comments, another approach is that you set the value of mySharedObject externally before you begin whatever concurrent process you are attempting:
/* MyClass.java */
public class MyClass {
private static MyClass2 mySharedObject = null;
public static SetSharedObject(MyClass2 sharedObject) {
mySharedObject = sharedObject;
}
// The rest of the class
}
/* Elsewhere.java */
MyClass2 sharedObject = new MyClass2(someRandomClass);
MyClass.SetSharedObject(sharedObject);
// Do whatever you do with MyClass concurrency
I have a public class with a private class inside it:
public class Out
{
private class In
{
public String afterLogic;
public In(String parameter)
{
this.afterLogic = parameter+"!";
}
}
}
And wanted to test the In class with jMockit. Something along these lines:
#Test
public void OutInTest()
{
Out outer = new Out();
Object ob = Deencapsulation.newInnerInstance("In", outer); //LINE X
}
The problema is, in LINE X, when trying to cast ob to In, the In class is not recognized.
Any idea how to solve this?
Thanks!
The only constructor in class In takes a String argument. Therefore, you need to pass the argument value:
Object ob = Deencapsulation.newInnerInstance("In", outer, "test");
As suggested in the comment one way is to change the access modifier of the inner class from private to public.
Second way (in case you don't want to make your inner class public), you can test the public method of outer class which is actually calling the inner class methods.
Change the scope of the inner class to default then make sure that the test is in the same package.
There are two approaches, first as mentioned in other posts to change the scope to public. The second which I support is, to avoid testing private class altogether. Since the tests should be written against testable code or methods of the class and not against default behavior.
I'm new to Java but experienced in C++. I came across some code that I didn't understand:
public class SomeClass {
private SomeOtherClass someOther = new SomeOtherClass();
private AThirdClass thirdClass;
SomeClass() {
this.thirdClass = new AThirdClass();
}
}
Why when there is only a single constructor would you have someOther initialized in the initialization and thirdClass initialized in the constructor?
The below is one reason you may wish to do that.
public class SomeClass {
private SomeOtherClass someOther = new SomeOtherClass();
private AThirdClass thirdClass;
SomeClass( int x ) {
this.thirdClass = new AThirdClass( x );
}
}
But that only explains why you would want to initialize thirdClass in the constructor. I am at a loss to explain why you would want to initialize someOther in the init block.
There is absolutely no reason, unless you get into static declarations, in which case it could make some sense.
There's nothing in your example that would suggest a reason, but underlying implementations may have problematic and poorly-considered code to consider. It may be important for you to know that the initialization of SomeOtherClass in your example will always run before the initialization in the constructor. Someone may have thought that was important.
Or, it could simply be two different developers with two different style preferences. Neither is technically wrong, but both have their (dis)advantages.
The default way to implement singleton pattern is:
class MyClass {
private static MyClass instance;
public static MyClass getInstance() {
if (instance == null) {
instance = new MyClass();
}
return instance;
}
}
In an old project, I've tried to simplify the things writing:
class MyClass {
private static final MyClass instance = new MyClass();
public static MyClass getInstance() {
return instance;
}
}
But it sometimes fail. I just never knew why, and I did the default way.
Making a SSCCE to post here today, I've realized the code works.
So, I would like to know opinions..
Is this a aleatory fail code?
Is there any chance of the second approach return null?
Am I going crazy?
--
Although I don't know if is the right answer for every case, it's a really interesting answer by #Alfred:
I also would like to point out that singletons are testing nightmare and that according to the big guys you should use google's dependency injection framework.
The recommended (by Effective Java 2nd ed) way is to do the "enum singleton pattern":
enum MyClass {
INSTANCE;
// rest of singleton goes here
}
The key insight here is that enum values are single-instance, just like singleton. So, by making a one-value enum, you have just made yourself a singleton. The beauty of this approach is that it's completely thread-safe, and it's also safe against any kinds of loopholes that would allow people to create other instances.
The first solution is (I believe) not thread-safe.
The second solution is (I believe) thread-safe, but might not work if you have complicated initialization dependencies in which MyClass.getInstance() is called before the MyClass static initializations are completed. That's probably the problem you were seeing.
Both solutions allow someone to create another instance of your (notionally) singleton class.
A more robust solution is:
class MyClass {
private static MyClass instance;
private MyClass() { }
public synchronized static MyClass getInstance() {
if (instance == null) {
instance = new MyClass();
}
return instance;
}
}
In a modern JVM, the cost of acquiring a lock is miniscule, provided that there is no contention over the lock.
EDIT #Nate questions my statement about static initialization order possibly causing problems. Consider the following (pathological) example:
public ClassA {
public static ClassB myB = ClassB.getInstance();
public static ClassA me = new ClassA();
public static ClassA getInstance() {
return me;
}
}
public ClassB {
public static ClassA myA = ClassA.getInstance();
public static ClassB me = new ClassB();
public static ClassB getInstance() {
return me;
}
}
There are two possible initialization orders for these two classes. Both result in a static method being called before the method's classes static initialization has been performed. This will result in either ClassA.myB or ClassB.myA being initialized to null.
In practice, cyclic dependencies between statics are less obvious than this. But the fact remains that if there is a cyclic dependency: 1) the Java compiler won't be able to tell you about it, 2) the JVM will not tell you about it. Rather, the JVM will silently pick an initialization order without "understanding" the semantics of what you are trying to do ... possibly resulting in something unexpected / wrong.
EDIT 2 - This is described in the JLS 12.4.1 as follows:
As shown in an example in §8.3.2.3, the fact that initialization code is unrestricted allows examples to be constructed where the value of a class variable can be observed when it still has its initial default value, before its initializing expression is evaluated, but such examples are rare in practice. (Such examples can be also constructed for instance variable initialization; see the example at the end of §12.5). The full power of the language is available in these initializers; programmers must exercise some care. ...
The second example is preferable, since the first isn't thread safe (as pointed out in the comments). The first example uses a technique called lazy instantiation (or lazy initialization), which ensures that the Singleton instance isn't created unless it's actually needed. This isn't really necessary in Java because of the way Java handles class loading and static instance variable initialization.
I also would like to point out that singletons are testing nightmare and that according to the big guys you should use google's dependency injection framework.
Remember, you need to declare a private constructor to ensure the singleton property.
The second case could be even simpler with just
class MyClass {
public static final MyClass instance = new MyClass();
private MyClass() {
super()
}
}
`
As others have noted, the first is not thread-safe. Don't bother with it as the second is perfectly fine, and will instantiate the object only when MyClass is referenced. Further it makes the reference final which expresses the intent better.
Just make sure that the declaration
private static final MyClass INSTANCE = new MyClass();
is the first static declaration in your class to avoid risk of calls to getInstance() or INSTANCE before it is initialized.
Don't forget the SingletonHolder pattern. See this SO question.
I don't know the answers to your questions, but here is how I might structure the same thing.
class MyClass {
private static MyClass instance;
static {
instance = new MyClass();
}
private MyClass() { }
public static MyClass getInstance() {
return instance;
}
}
I see this idiom of initializing instance variables quite a bit
public class Test{
private Long l = 1l;
private MyClass mc = new MyClass();
public Test(){}
...
}
But I would prefer
public class Test{
private Long l;
private MyClass mc;
public Test(){
l = 1l;
mc = new MyClass();
}
...
}
Considering that these are non-final variables, are the 2 approaches equivalent or is one "more" correct than the other in terms of thread safety?
Thread safety isn't an issue because this happens at construction phase, and two threads cannot be constructing the same object. Well, if you let this escape from the constructor, it might be possible for another thread to access the object during construction, but you really shouldn't do that. Functionality-wise, the two options are the same, so even if there were thread-safety issues, they would affect both the same way.
The first option, of initializing the fields at their declaration, is not always possible if you need to do some computation that cannot be done in an initializer (even then, you can keep the initialization out of the constructor if you do it in an initializer block, though). But if either way is possible, then it's purely a style issue, and I don't think there is a clear preference among Java programmers, so go with whichever seems better to you.
since your variables are instance variables, not class variables, you don't have a thread safety issue during initialization using either method. I'm sure others will chime in if there's a Java-standard-recommended best practice.
I think it's the matter of personal preference and your project coding standards.
Just make sure you only initialize variables in one place ( either constructor, or inline ).
Having initialization work done in the constructor gives you a better place for exception handling.
They are both not thread-safe. If thread A constructs the object, then thread B may or may not observer an incompletely initialized Test object or MyClass object. The visibility guarantees after a constructor exits only apply to final fields.
See http://pveentjer.wordpress.com/2007/03/18/immutability-doesnt-guarantee-thread-safety/
In terms of thread safety, they are equivalent. Both will need to execute the same instructions, and if you prefer the second (which I agree with you in your preference) then I would use that. If you want thread safety around a constructor, you would need a synchronized call around the constructor call.
I am not sure if this was answered earlier. But, I have a doubt on the following scenario:
I am trying to create a #Component class where in, I have an instance variable. Now, I want to create a new object of the instance variable for each request. I am not sure which one is the right way to do it?
**Option 1:**
#Component
public class ClassA {
private ClassB classB = new ClassB();
public ClassB create(){
return classB;
}
}
**Option 2:**
#Component
public class ClassA {
private ClassB classB = null;
public ClassB create(){
classB = new ClassB();
return classB;
}
}
**Option 3:**
#Component
public class ClassA {
public ClassB create(){
ClassB classB = new ClassB();
return classB;
}
}