I have recently found what appears to me to be a new syntax for statically initializing an ArrayList:
new ArrayList() {{
add("first");
add("second");
}};
My question is, what is really happening there? Is that a shortcut for defining a static block (I thought it would need the static keyword)? Or just a way to define a default constructor? Something else? What version of Java did this become valid?
An explanation plus a link to further reading would be greatly appreciated.
edit:
My test class for showing whether initializer block executes before or after the constructor is below. Results show that initializer blocks execute before the other constructor code:
import org.junit.Test;
public class InitializerBlockTest {
class InitializerTest {
{
System.out.println("Running initalizer block");
}
public InitializerTest() {
System.out.println("Running default constructor");
}
}
class SubClass extends InitializerTest {
{
System.out.println("Running subclass Initializer block");
}
public SubClass() {
System.out.println("Running subclass constructor");
}
}
#Test
public void testIt() {
new SubClass();
}
}
Output:
Running initalizer block
Running default constructor
Running subclass Initializer block
Running subclass constructor
You are creating a new anonymous subclass of ArrayList, with an instance initializer which calls add() twice.
It's the same as:
class MyList extends ArrayList
{
{ // This is an instance initializer; the code is invoked before the constructor.
add("first");
add("second");
}
public MyList() {
super();
// I believe initializers run here, but I have never specifically tested this
}
}
...
List list=new MyList();
Note that, personally, I do not advise it as an idiom, since it will lead to class-file explosion.
It is an initializer block for instance variables.
From Oracle's documentation:
Initializer blocks for instance
variables look just like static
initializer blocks, but without the
static keyword:
{
// whatever code is needed for initialization goes here
}
The Java compiler copies initializer
blocks into every constructor.
Therefore, this approach can be used
to share a block of code between
multiple constructors.
See: http://download.oracle.com/javase/tutorial/java/javaOO/initial.html
When you write new ArrayList() { } you are creating an anonymous subclass of ArrayList. The { } as in the innermost brackets in your code denote an initializer block and is actually copied into every constructor.
EDIT: You guys sure answer fast!
Related
My question is about one particular usage of static keyword. It is possible to use static keyword to cover a code block within a class which does not belong to any function. For example following code compiles:
public class Test {
private static final int a;
static {
a = 5;
doSomething(a);
}
private static int doSomething(int x) {
return (x+5);
}
}
If you remove the static keyword it complains because the variable a is final. However it is possible to remove both final and static keywords and make it compile.
It is confusing for me in both ways. How am I supposed to have a code section that does not belong to any method? How is it possible to invoke it? In general, what is the purpose of this usage? Or better, where can I find documentation about this?
The code block with the static modifier signifies a class initializer; without the static modifier the code block is an instance initializer.
Class initializers are executed in the order they are defined (top down, just like simple variable initializers) when the class is loaded (actually, when it's resolved, but that's a technicality).
Instance initializers are executed in the order defined when the class is instantiated, immediately before the constructor code is executed, immediately after the invocation of the super constructor.
If you remove static from int a, it becomes an instance variable, which you are not able to access from the static initializer block. This will fail to compile with the error "non-static variable a cannot be referenced from a static context".
If you also remove static from the initializer block, it then becomes an instance initializer and so int a is initialized at construction.
Uff! what is static initializer?
The static initializer is a static {} block of code inside java class, and run only one time before the constructor or main method is called.
OK! Tell me more...
is a block of code static { ... } inside any java class. and executed by virtual machine when class is called.
No return statements are supported.
No arguments are supported.
No this or super are supported.
Hmm where can I use it?
Can be used anywhere you feel ok :) that simple. But I see most of the time it is used when doing database connection, API init, Logging and etc.
Don't just bark! where is example?
package com.example.learnjava;
import java.util.ArrayList;
public class Fruit {
static {
System.out.println("Inside Static Initializer.");
// fruits array
ArrayList<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Orange");
fruits.add("Pear");
// print fruits
for (String fruit : fruits) {
System.out.println(fruit);
}
System.out.println("End Static Initializer.\n");
}
public static void main(String[] args) {
System.out.println("Inside Main Method.");
}
}
Output???
Inside Static Initializer.
Apple
Orange
Pear
End Static Initializer.
Inside Main Method.
The static block is a "static initializer".
It's automatically invoked when the class is loaded, and there's no other way to invoke it (not even via Reflection).
I've personally only ever used it when writing JNI code:
class JNIGlue {
static {
System.loadLibrary("foo");
}
}
This is directly from http://www.programcreek.com/2011/10/java-class-instance-initializers/
1. Execution Order
Look at the following class, do you know which one gets executed first?
public class Foo {
//instance variable initializer
String s = "abc";
//constructor
public Foo() {
System.out.println("constructor called");
}
//static initializer
static {
System.out.println("static initializer called");
}
//instance initializer
{
System.out.println("instance initializer called");
}
public static void main(String[] args) {
new Foo();
new Foo();
}
}
Output:
static initializer called
instance initializer called
constructor called
instance initializer called
constructor called
2. How do Java instance initializer work?
The instance initializer above contains a println statement. To understand how it works, we can treat it as a variable assignment statement, e.g., b = 0. This can make it more obvious to understand.
Instead of
int b = 0, you could write
int b;
b = 0;
Therefore, instance initializers and instance variable initializers are pretty much the same.
3. When are instance initializers useful?
The use of instance initializers are rare, but still it can be a useful alternative to instance variable initializers if:
Initializer code must handle exceptions
Perform calculations that can’t be expressed with an instance variable initializer.
Of course, such code could be written in constructors. But if a class had multiple constructors, you would have to repeat the code in each constructor.
With an instance initializer, you can just write the code once, and it will be executed no matter what constructor is used to create the object. (I guess this is just a concept, and it is not used often.)
Another case in which instance initializers are useful is anonymous inner classes, which can’t declare any constructors at all. (Will this be a good place to place a logging function?)
Thanks to Derhein.
Also note that Anonymous classes that implement interfaces [1] have no constructors. Therefore instance initializers are needed to execute any kinds of expressions at construction time.
"final" guarantees that a variable must be initialized before end of object initializer code. Likewise "static final" guarantees that a variable will be initialized by the end of class initialization code. Omitting the "static" from your initialization code turns it into object initialization code; thus your variable no longer satisfies its guarantees.
You will not write code into a static block that needs to be invoked anywhere in your program. If the purpose of the code is to be invoked then you must place it in a method.
You can write static initializer blocks to initialize static variables when the class is loaded but this code can be more complex..
A static initializer block looks like a method with no name, no arguments, and no return type. Since you never call it it doesn't need a name. The only time its called is when the virtual machine loads the class.
when a developer use an initializer block, the Java Compiler copies the initializer into each constructor of the current class.
Example:
the following code:
class MyClass {
private int myField = 3;
{
myField = myField + 2;
//myField is worth 5 for all instance
}
public MyClass() {
myField = myField * 4;
//myField is worth 20 for all instance initialized with this construtor
}
public MyClass(int _myParam) {
if (_myParam > 0) {
myField = myField * 4;
//myField is worth 20 for all instance initialized with this construtor
//if _myParam is greater than 0
} else {
myField = myField + 5;
//myField is worth 10 for all instance initialized with this construtor
//if _myParam is lower than 0 or if _myParam is worth 0
}
}
public void setMyField(int _myField) {
myField = _myField;
}
public int getMyField() {
return myField;
}
}
public class MainClass{
public static void main(String[] args) {
MyClass myFirstInstance_ = new MyClass();
System.out.println(myFirstInstance_.getMyField());//20
MyClass mySecondInstance_ = new MyClass(1);
System.out.println(mySecondInstance_.getMyField());//20
MyClass myThirdInstance_ = new MyClass(-1);
System.out.println(myThirdInstance_.getMyField());//10
}
}
is equivalent to:
class MyClass {
private int myField = 3;
public MyClass() {
myField = myField + 2;
myField = myField * 4;
//myField is worth 20 for all instance initialized with this construtor
}
public MyClass(int _myParam) {
myField = myField + 2;
if (_myParam > 0) {
myField = myField * 4;
//myField is worth 20 for all instance initialized with this construtor
//if _myParam is greater than 0
} else {
myField = myField + 5;
//myField is worth 10 for all instance initialized with this construtor
//if _myParam is lower than 0 or if _myParam is worth 0
}
}
public void setMyField(int _myField) {
myField = _myField;
}
public int getMyField() {
return myField;
}
}
public class MainClass{
public static void main(String[] args) {
MyClass myFirstInstance_ = new MyClass();
System.out.println(myFirstInstance_.getMyField());//20
MyClass mySecondInstance_ = new MyClass(1);
System.out.println(mySecondInstance_.getMyField());//20
MyClass myThirdInstance_ = new MyClass(-1);
System.out.println(myThirdInstance_.getMyField());//10
}
}
I hope my example is understood by developers.
The static code block can be used to instantiate or initialize class variables (as opposed to object variables). So declaring "a" static means that is only one shared by all Test objects, and the static code block initializes "a" only once, when the Test class is first loaded, no matter how many Test objects are created.
The static initializer blocks are invoked (in the order they were defined in) when the JVM loads the class into memory, and before the main method. It's used to conditionally initialize static variables.
Similarly we have the instance initializer blocks (aka IIBs) which are invoked upon object instantiation, and they're generally used to de-duplicate constructor logic.
The order in which initializers and constructors are executed is:
Static initializer blocks;
Object initializer blocks;
Constructors;
I have following code that I came across and having hard time to understand it.
Is this using anonymous class + anonymous method ?
public class TestClass {
protected boolean getValue() {
return true;
}
}
public class Main {
public static void main(String[] args) {
TestClass testClass = new TestClass() {
{
// call TestClass.getValue()
boolean value = getValue();
}
};
}
}
The block in the anonymous class declaration isn't an "anonymous method"; it's an "instance initializer". See JLS 8.6, which says "An instance initializer declared in a class is executed when an instance of the class is created". So when the code creates the new object testClass, it also executes the initializer, which calls getValue() and stores the result in a local boolean variable. However, this variable is local to the initializer block, and therefore the value will no longer be accessible after the initializer is done executing. So as written, the instance initializer does not do anything useful. (However, if you cut out a lot of code just to keep your code snippet smaller, I can understand that.)
I would like to understand what is this called. I saw this program in oracle website. I have kept breakpoint and saw this statment is called after static block and before constructor is called.
What is signifiance of this statement ?
{
System.out.print("y ");
}
In this code :
public class Sequence {
Sequence() {
System.out.print("c ");
}
{
System.out.print("y ");
}
public static void main(String[] args) {
new Sequence().go();
}
void go() {
System.out.print("g ");
}
static {
System.out.print("x ");
}
}
static {
System.out.print("x ");
}
Its the static block and its called whenever class is loaded. In general anonymous means which does not have any name like anonymous class are clases which does not have any name and their implementation is provided right at the place where it is required and can't be reused
{
System.out.print("y ");
}
As Eran commented out ,It's an instance initialization block, and it's executed whenever an instance is created and is called even before constructor.
It is an initializer block. It is executed whenever a new instance of a class is created. Most of the time you don't really need it, because instance initialization can also be put in the constructor. The initializer block is mainly there to initialize anonymous inner classes, for which you cannot define your own constructors (because to define a constructor you need the name of the class).
This is known as a static initialization block, or static initializer.
See: https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
Personally, I prefer not to use them exactly for the reason stated in the documentation I sited.
There is an alternative to static blocks — you can write a private
static method: The advantage of private static methods is that they
can be reused later if you need to reinitialize the class variable.
I have a class similar to the below one with all static methods. Hence the class was not initialized while used in other classes. I have to check a condition before invoking any static methods from this class. Even if i add a default constructor it will not get called. Could someone suggest ideas to have solution without instantiating this class in all of its usages? It need be a default constructor could be a simple other solution.
I need to check everytime the network connectivity before making the call. Static Initializer gets called only first time on load.
public class ABCServerUtil {
public static boolean checkServer() {...bla...bla...}
}
I need some thing like below piece of code to be called and to be exit.
public ABCServerUtil(){
if(!isNetworkOnline())
return;
}
If you need to check the condition every time one of the static methods is called, you don't have much choice but to do what you're doing: Call a method to do the check at the beginning of each of those methods.
If you only need to check the condition once when the class is initially loaded/initialized, you can use a static initializer:
public class ABCServerUtil {
static {
// Code here runs when the class is loaded
}
// ...
}
Use a static Initialization block
static {
//whatever code for initialization
}
A class can have any number of static initialization blocks
they can appear anywhere in the class body
static initialization blocks are called in the order that they appear in the source code.
You should be called every time when method called
public class Test {
public static void checkServer() {
if (!checkNetwork()) {
return;
}
}
public static void checkClient() {
if (!checkNetwork()) {
return;
}
}
private static boolean checkNetwork() {
return true; // or false depending on network condition
}
}
You can use a static initialiser.
static {
// code here
}
It will be run before any method of property (static or otherwise) of the class is first accessed.
you can directly call a static method with the class name like this,
boolean val=ABCServerUtil.checkServer();
some tutorial is given here
Since there's already 5 answers saying the same thing and none of them seem to be what you're after:
A tool like Byte Buddy sounds like what you need.
I think that this is your solution: Static initializer in Java
In practice you need a block of code executed the first time that your class is loaded.
When studying the java programming language, I meet the following statement
I am confusing about the statement marked with yellow. Especially, what does instance method mean here? If there is an example to explain this point, then it would be much appreciated.
If I have a method:
public static void print(String line) {
System.out.println(line);
}
... and then remove the static keyword ...
public void print(String line) {
System.out.println(line);
}
... it is now an instance method, can no longer be invoked from the class, and must instead be invoked from an instance (hence the name).
e.g.,
MyClass.print(line);
vs.
new MyClass().print(line);
That's really it.
You can call static methods without needing to intantiate an object:
TestObject.staticMethodCall();
For non-static methods you need to create an instance to call a method on:
new TestObject().nonStaticMethodCall();
Consider following sequence.
Define Class X with static void foo() a static method
Define Class Y which calls X.foo() in its main method
Compile the two classes and (somehow) run it
Change X.foo() to be a instance method by removing the static qualifier
Compile only X, not Y
Run the Y class again and observe the error.
On the other hand, if you had changed the body of X.foo in certain ways without changing its static-ness then there would have been no error. For more, look up "binary compatibility"
First of all, you should understand the difference between the class method and the instance method. An example is shown below.
public Class Example{
public static void main(String[] args) {
Example.method1();//or you can use method1() directly here
Example A = new Example();
A.method2();
}
public static void method1(){
}
public void method2(){
}
}
method1 is the class method which you can take it as the method of the class. You can invoke it without initiating a object by new method. So you can invoke it in such way: Example.method1()
method2 is the instance method which requires you to invoke it by initiating the instance of an object, i.e. Example A = new Example(); A.method2();
Additional:
The error is due to the removal of the static modifier of an class method like method1. Then method1 becomes an instance method like method2 which you have to initiate an instance to call.