What is the alternative to a static initialization block? - java

My projects had some developer who loved a static initialization block. What is the alternative to this? What is the downside of this alternative?
public class BlockTest {
String test = new String();
static{
test = "test string";
}
}
As far as I understood the static initialization block is used to set values of static field if it cannot be done in one line. But I do not understand why we need a special block for that. This leads to less readability and some confusion.

The example is not good. First of all it does not compile, you cannot assign a instance variable from static init block. But if even it were correct
public class BlockTest {
static String test = new String();
static{
test = "test string";
}
it would make no sense since it is equivalent to
public class BlockTest {
static String test = "test string";
but this static init block has no alternative
public class Object {
private static native void registerNatives();
static {
registerNatives();
}
...

It can be used for performing all the tasks that needs to be done when the class is referred for the first time, even before the instances of the class are created. It could have call to different methods or just initialization of static members. Static block ensures that these activities will be performed only once in the lifetime of the class and will be performed before any other operation takes place with regard to the class.
Programmer can depend on static block as it is ensured that the block will be executed only once and before any other activity related to that class is performed.
Moreover, I do not think it hampers readability at all. It again may vary from person to person.

If you have static members in your class which require a longer handling, you won't get around a static initializer (constructor). These must be initialized somewhere after all. You could do that in the constructor of your class, but then you would reinitialize these values EVERYTIME you create a new object.
There is no real alternative if you must handle more than just a simple initialization.
See this post and this.

If you have simple assignments, you can do the assignment directly in the member declaration. No need for a separate block which just extends the complexity and readabillity.
An alternative would be to use a lazy initialization. Advantage is that it can also be arbitrary complex, but is only executed when actually needed. But of course this only works if you have getters in your classes. If you access the members directly, then this would be a big change.

IMHO,There is no need for static block.
String test = "test string";
And From docs
Instance variables can be initialized in constructors, where error handling or other logic can be used. To provide the same capability for class variables, the Java programming language includes static initialization blocks.
But
Note: It is not necessary to declare fields at the beginning of the class definition, although this is the most common practice. It is only necessary that they be declared and initialized before they are used.

Related

JAVA: difference between Static method invocation with className and with Object of instance

I'm little confused on the calling static methods, any way i know this kind of rule
Foo.staticMethod(); //accessing static method.
for non-static method we must instantiate the class.
Foo person1 = new Foo(); //instantiating
person1.nonStaticMethod(); //accessing non-static method.
so all we know that static methods are known among the class so does not give a sens when we call it within the object reference like in Doc Oracle
its say :
Note: You can also refer to static methods with an object reference like
instanceName.methodName(args)
but this is discouraged because it does not make it clear that they are class methods.
Finally my question is as below:
public class Foo{
static int x = 10;
public static void method(){
System.out.println("ANYTHING TO SHOW !!!!");
}
public static void main(String[] args) {
Foo object = new Foo();
object.method(); // ANYTHING TO SHOW !!!!
Foo.method(); // ANYTHING TO SHOW !!!!
System.out.println(object.x); // Will display as result 10
System.out.println(Foo.x); //Also this will display as result 10
}
}
So why the documentation montioned that static field/method not longer with object ref while is give the same.
Note :
I know the uses of static keyword, that give smooth ref into memory which each variable declared once into the memory while is
attached to static keyword, also i know very well that static keyword
useful for hiding method from overriding when we deal with inheritance.
so these not included into my question.
By convention...
If one sees object.method(), they assume that method() is an instance method and requires an instance of Foo to be used.
If one sees Foo.method(), they know that method() is a static method and does not require an instance of Foo to be used.
This is a code readability issue more than a functional issue, since you demonstrate correctly that the code will work in either scenario. However, it does make understanding that code harder, since now the developer has to be wary of any other possible use of a static method in that fashion.
Remember: static methods don't require an instance for a reason. If you find yourself needing an instance for the method at all, it may be worth reconsidering its design.
Because the local variable x is static. If it were private, Foo.x wouldn't work and would return an error. Static methods, variables, etc. can be called by using ClassName.staticThing or by instance.staticThing. Since the variable x was static, it was able to be called by both object.x and Foo.x. If x were to be a private variable, Foo.x wouldn't work.

Why is it possible for objects to change the value of class variables?

By Oracle's definition,
Sometimes, you want to have variables that are common to all objects. This is accomplished with the static modifier. Fields that have the static modifier in their declaration are called static fields or class variables. They are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memory.
By this definition, it is safe to deduce that a static variable belongs to the class and shouldn't be accessible for modification by any object of the class.Since all objects share it.
So this line from the same definition is a bit confusing:
Any object can change the value of a class variable...
So I tried this code and it prints 45 (although I get a warning saying "Static member accessed via instance reference"):
public class Main {
static int value = 8;
public static void main(String[] args) {
// write your code here
Main main = new Main();
main.value = 45;
System.out.println(value);
}
}
If this was a Student class, and I had a static variable called numberOfStudents, why should one object of that class be allowed to change the value of this class variable?
It's not really that "one object" can - it's just you're in code which has access to that variable, and unfortunately Java allows you to access static members (both variables and methods) as if they were instance members. This ends up with very misleading code, e.g.
Thread t = new Thread(...);
t.start();
t.sleep(1000);
The last line looks like it's asking the newly-started thread to sleep - but actually it'll make the current thread sleep.
This is basically a flaw in Java. The compiler will silently turn code like this into
Thread.sleep(1000);
or in your case
Main.value = 45;
(I believe that in an older version of Java, it would emit code that checked for nullity with the variable you were accessing the static member "through", but it doesn't even do that any more.)
Many IDEs will allow you to flag code like this with a warning or error. I would encourage you to turn on such a feature. If you see existing code like that, change it to use access the static member directly via the declaring class, so it's clear what's going on.
By this definition, it is safe to deduce that a static variable belongs to the class and shouldn't be accessible for modification by any object of the class.Since all objects share it.
No, static field is accessible for modifications, as long the access modifier allows it.
main.value = 45;
The compiler will read this line at compile-time as:
Main.value = 45;
Being able to create a class with static variables and methods so that those variables and methods are shared by all instances or objects created from the class can be very useful, see When to use static methods.
When sharing a static variable in a class between multiple instances or objects created from the class, the synchronized modifier may be required in order to ensure that if the static variable is being modified by objects in more than one thread, that data integrity is maintained, see What does synchronized mean? and also see How to synchronize a static variable among threads running different instances of a class in java.
The final key word, see How final keyword works is used to determine whether a variable is immutable or not. So if you want to have a class static variable that should be immutable or a constant then you can add the final modifier to the definition. However see Java final keyword for variables which explains that the underlying value for a reference may not be immutable in the sense that functional programming means. See also what is meant by immutable as well as Why final keyword is necessary for immutable class.
You can also use modifiers such as public to determine the visibility of variables and methods in a class, see What does public static void mean in Java.
By using modifiers such as final or private the programmer is able to finely tune the visibility and modifiability of variables in class and objects instantiated from the class.
Litle example how the compiler change the object field access to a class field access.
public class A {
static int foo = 25;
static public void main(String[] arg){
B b = new B();
A a = b;
System.out.println(b.foo);
System.out.println(a.foo);
}
}
class B extends A {
static int foo = 60;
}
The output is:
60
25
It also shows that can be confiusing as it have different behaviour as for object fields.
By this definition, it is safe to deduce that a static variable belongs to the class and shouldn't be accessible for modification by any object of the class.Since all objects share it.
No. By this definition, that static variable belongs to the class and is modifiable by any instance of the class. There is no implication that when some variable is shared that it should not be modifiable. Use final if you want that.
If this was a Student class, and I had a static variable called numberOfStudents, why should one object of that class be allowed to change the value of this class variable?
To increment the value in constructor and decrement it in finalizer, for example.
A static variable has a single instance for the whole class that defines it. When an instance is created, an instance of that static variable IS NOT CREATED. There is only one, and that one is freely modifiable by any function without the need for an instance. (unless it is declared final)

Static method on a class with a private constructor that internally creates itself

This is more of a "is this safe, stupid, or completely unnecessary" question. I'm trying to figure out if this code pattern is reasonable:
public class SomeClass {
private String someField;
// Other fields here omitted for clarity
private SomeClass() {
someField = "some initialization goes here";
// More initialization of omitted fields
}
public static void doSomething(MyObject myObject) {
SomeClass someClass = new SomeClass();
// Do things with myObject and someClass instance
}
}
Is there an obvious (or non-obvious) problem with this code? I think the general goal was to separate the complexity of activity in the doSomething method from elsewhere in the code, but still leave the SomeClass class open for flexibility. Maybe?
Would there be concurrency/synchronization problems with something like this?
I apologize for the very ambiguous example code.
There would not be any concurrency or synchronization problems with this concept, because for every call to the static method, there is an individual instance of SomeClass, meaning that no values will ever be accessed by multiple threads simultaneously.
As for the feasibility of this design pattern, I'd say it's a reasonable pattern. I can't think of any Java API classes which implement such a pattern, but I'll add any to this answer if I find some. Normally, you'll see classes with private constructors to not use the object and instead provide a bank of static methods, but there's not really any reason not to do what you're doing.
The way you are using it is a mix-up of static factories and normal object creation. So in your case, you won't have any concurrency issue.
But still, assuming that you wanted to know about static factory, using static factory is preferable, in case you just want a single instance of your class to roam around, or you can also use them to return an instance of any subtype.
It is the very first item in the book: - Effective Java that says, Consider static factory methods instead of constructors.
Here is a quote from the advantages listed in that item: -
One advantage of static factory methods is that, they have names,
unlike constructors. If parameters to a constructor do not, in and of
themselves, describe the object being returned, a static factory with
a well-chosen name is easier to use.
So, you can have different kinds of static methods with thier name showing what they will do. For E.G: -
getInstance() should generally be used to return the existing instance
newInstance() should be used to create new instance on every call
So, your singleton implementation should be like: -
public class Demo {
private static Demo demo = new Demo();
private Demo() {
}
public static Demo getInstance() {
return demo != null? demo: new Demo();
}
}

Java Static confusion

I'm working with Java; I have worked with C++ before. I am thinking about static usage in Java. If I create static methods and variables in the class, Why can I access them through the object also?
Example:
class Test{
static int count=0;
int id;
static void updatec(){
count++
}
}
class TestMain
{
public static void main(String args[])
{
Test.count=1;
Test t = new Test();
t.count=5; // Valid WHY ?????
}
}
Why this is allowed? Java's site says we should not use obj.static method/variable.
Why it is allowed?
Static doesn't mean that the field is only for the class. It means it for the class and all its instances.
In this example, the class variable origin of the class Point is referenced both using the class name as a qualifier, in Point.origin, and using variables of the class type in field access expressions (§15.11), as in p.origin and q.origin. These two ways of accessing the origin class variable access the same object, evidenced by the fact that the value of the reference equality expression (§15.21.3):
q.origin==Point.origin is true
But you're right it's usually a bad idea to refer to a static field/method/class from a non-static context, it can confuse the developer.
Resources :
JLS - static Fields
It's legal to access static fields through an instance, although you'll generally get a warning about it. The field is still static, however, so there's only one per class:
Test t = new Test();
Test u = new Test();
t.count = 5;
System.out.println(u.count); // Outputs 5
There is no good reason why this is allowed. It's confusing and it serves no purpose. Good tools will warn you about this (or maybe even give you the option to fail compilations over it). But it is part of the language and so it will never be taken out because that would break existing code.
It really should not have been supported. This support leads to this dubious code in org.apache.commons.cli command-line parser.
class OptionBuilder
public static Option create();
public static OptionBuilder withLongOpt(String newLongopt);
public static OptionBuilder withDescription(String newDescription);
This leads to this:
Option opt =
OptionBuilder
.withLongOpt( "opt" )
.withDescription( "opt description" )
.create( );
It would be much better and cleaner and thread-safe, if there were a default OptionBuilder constructor and all static methods were instance methods. That's the model used by StringBuilder/StringBuffer
Your snippet is perfectly legit, either in Java or C++ equivalent.
It seems you're confusing access restriction (private, protected, public) and instance/class distinction for members (static keyword).
Since you have an instance of class Test (named t) in your static main method, you can use instance methods/members of class Test, that's conforming with the documentation you quoted.
If the count field was private or protected, you wouldn't be able to access it, but that would have nothing to do with static.
You shouldn't doesn't mean you can't.
Anyway, this is allowed in C++ also.
static in this case means there's one shared instance per class, not per instance. So when you change t.count, you're changing the 'count' member for the whole class and ALL instances.
That is, these will print the same value:
System.out.println(t.count);
System.out.println(Test.count);
There's nothing illegal about it, although it's usually not a great idea because it looks like instance data.

Is static code always executed when we use a class for the first time?

Our application is using initialization code that depends on the order static code is executed and I'm wondering if this order will be consistent across all JVMs.
Here is a sample of what I mean:
public class Main {
static String staticVar = "init_value";
public static void main(String[] args) {
System.out.println(A.staticVar);
staticVar = "mainValue";
System.out.println(A.staticVar);
}
}
public class A {
static String staticVar = Main.staticVar;
}
will give:
init_value
init_value
and
public class Main {
static String staticVar = "init_value";
public static void main(String[] args) {
// System.out.println(A.staticVar);
staticVar = "mainValue";
System.out.println(A.staticVar);
}
}
public class A {
static String staticVar = Main.staticVar;
}
will give (on my environment):
mainValue
To summarize, across all JVMs, is static code always executed when we use a class for the first time?
EDIT: Despite all the reassurances below, if you're thinking of relying on this sort of thing, I would try hard to refactor your code so that it doesn't crop up. While it is guaranteed to work, it's also likely to make your code very brittle. The fact that static initializers get called "invisibly" makes them relatively hard to reason about and debug.
Yes, this is guaranteed by the language specification. From section 8.7 of the spec:
Any static initializers declared in a class are executed when the class is initialized and, together with any field initializers (§8.3.2) for class variables, may be used to initialize the class variables of the class (§12.4).
StaticInitializer: static Block
It is a compile-time error for a static initializer to be able to complete abruptly (§14.1, §15.6) with a checked exception (§11.2). It is a compile-time error if a static initializer cannot complete normally (§14.21).
The static initializers and class variable initializers are executed in textual order.
And from section 12.4:
Initialization of a class consists of
executing its static initializers and
the initializers for static fields
declared in the class. Initialization
of an interface consists of executing
the initializers for fields declared
in the interface.
Before a class is
initialized, its direct superclass
must be initialized, but interfaces
implemented by the class need not be
initialized. Similarly, the
superinterfaces of an interface need
not be initialized before the
interface is initialized.
A class or interface type T will be
initialized immediately before the
first occurrence of any one of the
following:
T is a class and an instance of T is
created.
T is a class and a static
method declared by T is invoked.
A
static field declared by T is
assigned.
A static field declared by T
is used and the field is not a
constant variable (§4.12.4).
T is a
top-level class, and an assert
statement (§14.10) lexically nested
Static initialisers (e.g. your staticVar declarations) are always executed when you use a class for the first time.
Static methods are only executed when they are called. In your case, this is happening because the static void main(String[] args) is the entry point to your application. But if you defined a different static method then it would not be called.
It is also possible to create a static initialiser block that will also be called automatically before the class is first used, e.g.
static {
// some initialisation code here
}
That should be all the same on all platforms. See JVM Specification : http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#19075
A quote from Java specification:
Initialization of a class consists of
executing its static initializers and
the initializers for static fields
declared in the class. Initialization
of an interface consists of executing
the initializers for fields declared
in the interface.
Yes, according to the Java Language Specification static code is always executed in the same order on all (compliant) JVM's.
8.7 Static Initializers
The static initializers and class variable initializers are executed in textual order.
Dittos to other posters, but let me add that a static initializer that depends on the state of other classes like in your example seems to me to make for very fragile and difficult-to-maintain code. I'll use static intializers to populate internal class data -- to fill up an array with default values or that sort of thing. But I don't think I've ever had one peek at the data in another class. Technically legal, and maybe there are odd cases where it's a good idea, but yuck.
Yes, I believe that would be the point by definition.
Static Block will always run first not just the first time... Before executing any code block, JVM execute the static code block first, and then only it run the code block as it has been designed...

Categories