This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is Double Brace initialization in Java?
While looking at some legacy code I came across something very confusing:
public class A{
public A(){
//constructor
}
public void foo(){
//implementation ommitted
}
}
public class B{
public void bar(){
A a = new A(){
{ foo(); }
}
}
}
After running the code in debug mode I found that the anonymous block { foo() } is called after the constructor A() is called. How is the above functionally different from doing:
public void bar(){
A a = new A();
a.foo();
}
? I would think they are functionally equivalent, and would think the latter way is the better/cleaner way of writing code.
{ foo(); }
is called instance initializer.
why?
As per java tutorial
The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors.
"Instance initializers are a useful alternative to instance variable initializers whenever: (1) initializer code must catch exceptions, or (2) perform fancy calculations that can't be expressed with an instance variable initializer. You could, of course, always write such code in constructors. But in a class that 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. Instance initializers are also useful in anonymous inner classes, which can't declare any constructors at all."Source
This was also quoted in this answer.
Unless the runtime class of the object is accessed (by means of calling getClass()) and needs to be different from A for some reason (for instance because it serves as super type token), there is indeed no difference, and simply invoking foo() after construction would indeed be the more common idiom.
Related
I couldn't find anything about this online, because I didn't know what to search for, but Java doesn't mark this code as having an error:
public class Test {
// ...
{
int test;
}
// ...
}
Does this serve any purpose in Java? If so, what?
This is called an instance initializer (JLS section 8.6)
When creating an object the instance initializer is run after super constructors but before the called constructor of the class they are defined in. See JLS 12.5 Creation of New Class Instances. Specifically, instance initializers are evaluated in step 4 of the object creation process. The key point is that instance initiailzers always get called no matter what constructor is used to instantiate the object.
There are also static initializers which are similar but marked with the static keyword.
public class Test {
static {
// Do something interesting on class load.
}
}
In my experience static intiailzers are more common as you can use them to setup complex class state (like linking JNI libraries) when the class is loaded.
This question already has answers here:
Use of Initializers vs Constructors in Java
(10 answers)
Closed 8 years ago.
I am studying for an exam about Java. While I was studying, I have encountered syntaxes in java which are unfamiliar to me. Such as a curly braces({}) unside a class body without a name, some has a static keyword. I have found out that they are called "Initializers". Can anyone help me point out key differences among them and how they differ from a Constructor. Thanks
The main difference between them is the order they are executed. To illustrate, I will explain them with an example:
public class SomeTest {
static int staticVariable;
int instanceVariable;
// Static initialization block:
static {
System.out.println("Static initialization.");
staticVariable = 5;
}
// Instance initialization block:
{
System.out.println("Instance initialization.");
instanceVariable = 10;
}
// Constructor
public SomeTest() {
System.out.println("Constructor executed.");
}
public static void main(String[] args) {
new SomeTest();
new SomeTest();
}
}
The output will be:
Static initalization.
Instance initialization.
Constructor executed.
Instance initialization.
Constructor executed.
Briefly talking:
Static initialization blocks run once the class is loaded by the JVM.
Instance initialization blocks run before the constructor each time you instantiate an object.
Constructor (obviously) run each time you instantiate an object.
A Constructor is called once when a new instance of a class is created. The values initialized in the constructor belong to the scope of the instance. Each Instance may have a different value for the same field initialized in the Constructor.
Static Initializers are useful for executing setup code in Static Classes and filling out data structures in Enums. They are called once, in order from top to bottom when the Class is loaded into the JVM and the data exists within the scope of the Class or Enum. All references to the Class will return the same value for fields initialized in the Static Initializers
Unnamed Curly Braces are Anonymous code blocks that scope reference names. If you create a reference inside the blocks, you can not get the value of that reference outside the block. If you find yourself needing them it's a sign you need to refactor your code into more methods.
This is the kind of thing you really need to look in your textbook to get an answer. However I can give you some pointers. Its been some years since I programmed Java, so any information I gave you is general.
Generally a nameless block with curly braces is an anonymous function. Static initializers initialize data that is global to all instances of that class, and runs once the first time the class is referenced. You need to be careful about how you use static properties or methods. With this information you can find accurate details in your text books.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Below is a program in which there are two static block which in my opinion should be called at first notice but in order from top to bottom but that does not happen
public class StaticTest {
public static void main(String[] args) {
A a1 = new A();
A a2 = new A();
B b1 = new B();
}
}
class A {
static {
System.out.println("Static block of Class A");
}
{
System.out.println("Non-Static block of a instance of Class A");
}
public A() {
System.out.println("Constructing object of type A");
}
}
class B {
static {
System.out.println("Static block of Class B");
}
{
System.out.println("Non-Static block of a instance of Class B");
}
public B() {
System.out.println("Constructing object of type A");
}
}
"Exactly at what time static block or method is invoked" - For question like this, the Java Language Specification has the answer for you.
Static initializer:
A static initializer declared in a class is executed when the class is
initialized. Together with any field initializers for class
variables, static initializers may be used to initialize the
class variables of the class.
By running your code, you can easily figure out what runs first.
The static block in class B is not executed until B is actually needed. This is only the case in the 3rd statement of the main method. In fact, if you replace that line with
if (2*2 == 5) new B();
you'll notice that the static block of B is never executed, because B will not even be loaded.
To trace class loading, use the -verbose:class option of the java command.
This is the output of your test
Static block of Class A
Non-Static block of a instance of Class A
Constructing object of type A
Non-Static block of a instance of Class A
Constructing object of type A
Static block of Class B
Non-Static block of a instance of Class B
Constructing object of type A
I guss you are surprised why Static block of Class A is printed only once. This is because the static block runs only once on class loading. After you called new A()
JVM loaded A.class and when you called new A() again there was no need to load it again
The static blocks are executed when the respective classes are initialized.
The order of class initialization is determined by a combination of the static and dynamic dependencies between the classes involved; see When does static class initialization happen?
However, the JLS is effectively providing a set of constraints (this occurs before that) for which there are often many solutions. And this is an example where two "solutions" to the constraints are possible.
The class A is initialized before the new A() expression constructs an A
The class B is initialized before the new B() expression constructs an B
As you can see, initialize class A before B and B before A are both solutions.
In a situation like this, the actual order of initialization is not specified, and is likely to be JVM and/or bytecode compiler dependent ... and should not be relied upon.
It is also possible to construct a scenario in which there is a cycle in the dependencies, which results in there being no order that satisfies the constraints. In this case, the order is also indeterminate, and one of the classes may observe the other class in an uninitialized state. (Neither the compiler or the runtime flags this as an error!) This is described in JLS section 8.3.2.3.
Fortunately, this situation is pretty unusual.
Instance blocks and static methods are much simpler:
The instance blocks of a class are executed in program order each time an instance is created. They are executed in order between a constructor's super(...) "call" and the next line of that constructor. (The same applies when the constructor is the default constructor and/or the super() call is implicit.)
A static method is executed when it is explicitly called.
following is the output of your program
Static block of Class A
Non-Static block of a instance of Class A
Constructing object of type A
Non-Static block of a instance of Class A
Constructing object of type A
Static block of Class B
Non-Static block of a instance of Class B
Constructing object of type A
Static block is called only once when first time class object is created
What is the rationale behind making this kind of code valid in java? Does it exist for some particular reason or is it just a byproduct of other Java language design decisions? Can't you just use the consructor to achieve the same effect?
class Student
{
{
System.out.println("Called when Student class is instantiated.");
}
}
One point is that it will execute whichever constructor is called. If you have several constructors and they don't call each other (for whatever reason, e.g. each wanting to call a directly-corresponding superclass constructor) this is one way of making sure the same code is executed for all constructors, without putting it in a method which could be called elsewhere.
It's also potentially useful when you're writing an anonymous class - you can't write a constructor, but you can write an initializer block. I've seen this used for JMock tests, for example.
It's called an initializer block.
The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors.
It called init block. In such block you can perform logic that are same for all constructions also you can separate declaration and initialization of same fields.
upd and of course double brace initialization, like
List<Integer> answers = new ArrayList<Integer>(){{add(42);}}
This is an initialization block. As mentioned by Matt Ball, they are copied into each constructor.
You might be interested to know about static initialization blocks (also in Matt's link):
public class Foo {
static {
System.out.println("class Foo just got initialized!");
}
{
System.out.println("an instance of Foo just got initialized!");
}
}
I've read elsewhere that a static anonymous class doesn't make sense - that all anonymous classes should be tied to an instance of the enclosing type. But the compiler let's you do it. Here's an example:
class Test {
/*
* What's the difference at between
* Test.likeThis and Test.likeThat?
*/
// This is obviously okay:
private static final class LikeThat {
#Override
public String toString() { return "hello!"; }
}
public static Object likeThat = new LikeThat();
// What about this - is it really any different?
public static Object likeThis = new Object() {
#Override
public String toString() { return "hello!"; }
};
}
What's going on here?
From the Java Language Specification, section 8.1.3:
An instance of an inner class I whose declaration occurs in a static context has no lexically enclosing instances. However, if I is immediately declared within a static method or static initializer then I does have an enclosing block, which is the innermost block statement lexically enclosing the declaration of I.
Your anonymous class (the one likeThis is an instance of) occurs in a static context, so it is not tied to an enclosing instance. However, it seems that it can refer to final variables of its enclosing block (see the rest of section 8.1.3, they give an example).
Btw, your wording is a bit deceptive, you're actually referring to a static instance of an anonymous class (it's the instance that's static, not the class).
I see nothing wrong with static anonymous classes
Like anything in any language you should just consider why you're doing it. If you've got alot of these instances then I'd question the design decisions, but it doesn't necessarily means it's a pattern that should never be followed.
And of course, always consider the testability of the class and whether you can provide a test double if the need arises
I don't think they have no sense. If you don't need reference to enclosing object then it's better to leave it static. Later it can evolve in separate class with ease.
Wide-spread enum idiom (pre Java 5) used similar approach with anonymous static inheritors of enum class. Probably, now it is better stick to Java 5 enum for this case.
If you are able to find adequate real-world application for anonymous static classes - why not to use them?
I do this all the time. It's especially handy for special-case implementations of utility interfaces, e.g.:
/** A holder for {#link Thing}s. */
public interface ThingsHolder {
/** A {#link ThingsHolder} with nothing in it. */
public static final ThingsHolder EMPTY_HOLDER = new ThingsHolder() {
#Override
public Iterable<Thing> getThings() {
return Collections.emptySet();
}
};
/** Provides some things. */
Iterable<Thing> getThings();
}
You could create a private static inner class called EmptyHolder, and maybe in some cases that would make the code more readable, but there's no reason you have to do it.
According to this answer which references the JLS, anonymous classes are never static, but when created in a "static context" they have no "enclosing instance".
That said,
They give the same error at compile time if you try to reference Test.this (non-static variable this cannot be referenced from a static context)
At runtime, the only obvious difference between the Class objects (apart from name) is that Test$1 is an "anonymous class" and Test$LikeThat is a "member class". Both of them have an enclosing class; neither of them have an enclosing constructor or method. (I only checked the likely-looking methods; there may be other differences.)
EDIT: According to getModifiers(), Test$1 is static and Test$LikeThat is static final! According to the language spec, Test$1 should actually be final. Hmm...
According to javap -c -verbose -s -private -l,
Test$1 specifies an "EnclosingMethod" (probably Test's static initializer?)
Test$LikeThat has an extra entry under "InnerClass" (#12; //class Test$1) and a curious constructor Test$LikeThat(Test$1). This appears to happen because LikeThat is private which makes the constructor private, so the compiler generates a "trampoline" to allow it to be called from Test.
If you remove the private, they appear to compile to roughly the same thing apart from the EnclosingMethod entry.
Test$1 does not have the field final Test this$0; that it would if it was defined in a non-static context.
Seems perfectly legitimate to me. Since the anonymous class is static it won't have a reference to any enclosing class, but there should be no evil consequences from that.
Well, other than being a hidden singleton object, that's pretty evil.
Of course they are not. I always use static nested classes, unless I need the implicit association to the enclosing object.
In java terminology nested class := a class which is declared within another class (or interface). Inner classes are those nested classes which have an associated instance from the enclosing class. (Nonstatic member classes, local classes, anonymous classes).
The implicit association can prevent garbage collection sometimes.
These can be very convenient because of possibility to make circular references:
class A
{
public static final A _1 = new A() {
public A foo()
{
return _2;
}
};
public static final A _2 = new A() {
public A foo()
{
return _1;
}
};
}
Creation of several objects which are holding references to each other can be very awkward without usage of anonymous classes.