Just wondering about the reason of compiling code like this:
class MyClass extends AnotherClass {
{
MySecondClass object = new MySecondClass();
object.doSomething();
}
}
Whats the difference between this code and code in constructor? This code executes before the object creation.
The code inside the braces with no names will be part of the constructor of the class and be executed before the logic contained in the class constructor.
Quick example:
public class Foo {
{
System.out.println("Before Foo()");
}
public Foo() {
System.out.println("Inside Foo()");
}
{
System.out.println("Not After Foo()");
}
}
This is called an instance initializer. The code in the initializer is inserted after the call to the super class constructor and before the rest of the constructor code.
The first operation of any constructor is to invoke a super class constructor. If a constructor is called explicitly, super(...), the specified constructor is used. If no constructor is explicitly invoked, the default constructor (with no arguments) is invoked in the super class. If no such constructor exists, it is a compile time error.
After this explicit or implicit constructor invocation, instance initializers are invoked in the order they appear in source code (yes, you can have more than one initializer).
To illustrate, running this program prints
Another constructor
Init 1
Init 2
Test constructor
class Another {
Another() { System.out.println("Another constructor"); }
}
class Test extends Another {
public static void main(String[] args) { new Test(); }
{ System.out.println("Init 1"); }
Test() { System.out.println("Test constructor"); }
{ System.out.println("Init 2"); }
}
The most commonly seen application is in the initalization the "double brace initialization" idiom, where an anonymous inner class is defined, and an instance is created and configured at once. Here's a fairly common example from Swing programming:
JButton popupButton = new JButton(new AbstractAction("Popup") {
{
putValue(Action.SHORT_DESCRIPTION, "Popup a dialog");
}
#Override
public void actionPerformed(ActionEvent evt)
{
popup();
}
});
This could be useful if you have multiple constructors, and need to perform some parameter-less initialization in every constructor. This could be factored into an initialization block.
This is an instance initialization block that runs before the constructor and if you ask why would one wanna use it in place of the constructor? The answer is no, you don't.
Just wondering about the reason of compiling code like this:
You usually use it to factor out common code when using constructor overloading. So, the "the" above actually refers to one of the overloaded constructors that gets called on object instantiation after the common instance initialization code block has executed.
By the way, you could sometimes achieve the same by calling one constructor from the other but the call then has to be on the first line inside the calling constructor or the code won't compile.
Related
I have created anonymous class by implementing interface I inside public static void main() method. So, by java 8 for the abstract method test(), the implementation is provided from imple() method of class C.
So, inside public static void main() method, printing _interface.getClass(), I got
package_path.Main$$Lambda$1/310656974 which is absolutely fine. Bacause it print's the anonymous class name.
Also, _interface is pointing to an anonymous object in heap and hence I'm doing _interface.test();
So, the first statement that test() method has now is to print the class name,
But eventually what it print was,
package_path.C (telling me C is the class name). How is that possible? Shouldn't package_path.Main$$Lambda$1/310656974 be printed again? Because 'this' means anonymous inside the test method right?
#java.lang.FunctionalInterface
interface I {
void test();
}
class C {
void imple() {
System.out.println(this.getClass());
System.out.println("Inside Implementation");
}
}
class Main {
public static void main(String[] args) {
I _interface = new C()::imple;
System.out.println(_interface.getClass());
_interface.test();
}
}
Hopefully, this might help you understand, that when you declare
I _interface = new C()::imple;
you've actually implemented the interface somewhat similar to (though not same as):
I _interface = new I() {
#Override
public void test() {
new C().imple(); // creating an instance of class `C` and calling its 'imple' method
}
};
Hence when the test method is called, it first creates an instance of C which prints
class x.y.z.C
as the class.
Because 'this' means anonymous inside the test method right?
Now as you can see above, there is no more anonymous class from which imple
is being called from, hence this is not representing the anonymous class anymore.
As Holger clarified in comments further, despite the representation as lambda or anonymous class at the calling site, the this.getClass() inside a method of class C will evaluate to C.class, regardless of how the caller looks like.
Recommend: Continue to read and follow on Is there any runtime benefit of using lambda expression in Java?
I'm studying CS and we have questions about polymorphism that I cant wrap my mind around. Here is an example:
public class AA{
public AA(){
foo();
}
private void foo() {
System.out.print("AA::foo ");
goo();
}
public void goo(){
System.out.print("AA::goo ");
}
}
public class BB extends AA{
public BB(){
foo();
}
public void foo(){
System.out.print("BB:foo ");
}
public void goo(){
System.out.print("BB::goo ");
}
public static void main(String[] args){
// Code goes here
}
}
When in void main i add the line:
AA a = new BB();
it goes first AA constructor prints AA:foo but then goo() sends it to BB's goo, why so?
Simple polymorphism such as "Animal -> cat/spider/dog" is easy to understand but when it comes to this I'm just lost. Can you guys give me any tips how to read this code? What are the rules are?
EDIT: there is no #Override annotation because this is a question from an exam.
Explanation
public class AA {
private void foo() { ... }
^^^^^^^
}
Polymorphism is not applied to private methods. A subclass does not inherit private methods, so they cannot be overridden:
A class C inherits from its direct superclass all concrete methods m (both static and instance) of the superclass for which all of the following are true:
m is a member of the direct superclass of C.
m is public, protected, or declared with package access in the same package as C.
No method declared in C has a signature that is a subsignature of the signature of m.
Java Language Specification - 8.4.8. Inheritance, Overriding, and Hiding
Therefore, the foo() call from the A constructor doesn't invoke BB#foo, it calls AA#foo.
But the goo() call within AA#foo refers to the overridden method BB#goo. Here, with public methods, method overriding and polymorphism were applied.
It's a bit tricky, so I would recommend you put the #Override annotation everywhere it's supposed to be.
public class BB extends AA {
#Override // it doesn't compile - no overriding here
public void foo() { ... }
#Override // it does override
public void goo() { ... }
}
It also might be helpful to detect another problem:
Programmers occasionally overload a method declaration when they mean to override it, leading to subtle problems. The annotation type Override supports early detection of such problems.
If a method declaration in type T is annotated with #Override, but the method does not override from T a method declared in a supertype of T, or is not override-equivalent to a public method of Object, then a compile-time error occurs.
Java Language Specification - 9.6.4.4. #Override
Illustration
If a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object, then the constructor body implicitly begins with a superclass constructor invocation super();, an invocation of the constructor of its direct superclass that takes no arguments.
Java Language Specification - 8.8.7. Constructor Body
To put it simply,
public BB() {
foo();
}
turns into
public BB() {
super();
foo();
}
Keeping super(); in mind, we can make the next illustration:
new BB()
AA() // super(); -> AA constructor
A#foo() // private method call
B#goo() // polymorphic method call
BB() // BB constructor
B#foo() // plain method call
It's explained very well in the official docs:
https://docs.oracle.com/javase/tutorial/java/IandI/super.html
If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass. If the super class does not have a no-argument constructor, you will get a compile-time error. Object does have such a constructor, so if Object is the only superclass, there is no problem.
So, the Java compiler is adding super() without args for you.
In fact, if the class you are extending doesn't have a default constructor you will be required to call this constructor with args before.
Otherwise, the reason why AA:goo is not being called is because is override by BB even if it doesn't have the #Override annotation, if you want to see that call you need to use super(); in your b:goo method. In fact, the foo is not override because it private so it's not possible to override it, if you try to add the annotation #Override you'll se you have a compilation failure.
AA::foo() is private so AA::foo() and BB::foo() aren't the same.
new BB()
will call AA::Constructor first, calling AA::foo().
AA::foo() call goo() and since you instantiated BB class it'll be BB::goo().
Please use "override" keyword on method when you want to do something like this
There is also a serious design flaw in the example code: it is calling an overridable method from a constructor. This means that object BB might not be fully initialized at the time that this method is called on it. For example:
public class AA{
public AA(){
foo();
}
private void foo() {
System.out.print("AA::foo ");
goo();
}
public void goo(){
System.out.print("AA::goo ");
}
}
public class BB extends AA{
private Date timestamp;
public BB() {
super();
foo();
timestamp = new Date();
}
public void foo() {
System.out.print("BB:foo ");
}
public void goo() {
// goo() gets called before timestamp is initialized
// causing a NullPointerException
System.out.print("BB::goo " + timestamp.getYear());
}
public static void main(String[] args){
AA obj = new BB();
}
}
Remember this: NEVER CALL AN OVERRIDABLE METHOD FROM A CONSTRUCTOR (even not indirectly as in this example)
Polymorphism is Simple yet Confusing at times when we use different set of names [Which is the case here].
Polymorphism is basically a Parent Child Relationship. Key here is, if you are trying hard to place the names of the classes, use yourself instead i.e. give comment line next to class names as below
public class AA{} //your Parent name
public class BB extends AA{} // yourself i.e. your name
When it comes to the code like this, AA a = new BB(); , decode the code as below:
BB is you, AA is your parent.
new keyword is with YOU(i.e. BB), so a new object of YOU would be created or born. In order to for YOU to born, without your parents(i.e. AA), you cannot exist and so, first they will be born or created (i.e. AA constructor would run). Once your Parents (i.e. AA) are created, then it is time for YOU to born(i.e. BB constructor would run).
In your example,
public AA(){
foo(); -- line A
}
private void foo() {
System.out.print("AA::foo ");
goo(); -- line B
}
public void goo(){
System.out.print("AA::goo "); -- line C
}
As I told earlier, Line A would be called when you say AA a = new BB(); as Line A is in Constructor of AA, Line A calls foo() method and so the control lands in foo(), prints "AA::foo " and executes Line B. Line B calls goo() method and so on it reaches Line C. After Line C is executed, there is nothing left to execute in AA constructor (i.e. Object is created) and so the control flows down to the child Constructor ( As parent is created, it is time for the child to born) and so the child Constructor would be called next.
For Students/Beginners, I strongly recommend to go through Head First Java Edition. It really helps you in laying the Java Foundation Strong.
Consider the following code :
public class TestClass
{
TestClass()
{
super();
System.out.printf("yes it is called");
}
public static void main(String[] args)
{
new TestClass();
}
}
Now as anonymous object is created , it calls the constructor. Now with super , it agian calls it self and again the process repeats . This should create infinite recursion.But this is not what happens . Why ?
This is not recursion. In a constructor, calling super(); calls the superclass constructor, not itself.
If you were to say this(); inside that constructor, then the compiler would catch "recursive constructor invocation" as a compiler error.
super() in your case just calls new Object() (all java classes inherit from the Object class), something that would happen anyway. No recursion here
super() is in reference to the superclass, you are calling Object's constructor.
If you were to make this infinite recursion, you would use this
public class SomeClass {
public SomeClass() {
this(); //recursion!
}
}
Of course, this is a compilation error.
I've this code snippet:
class Base {
public Base() {
method();
}
void method() {
System.out.println("In Base");
}
}
class Derived extends Base {
private String bar;
public Derived() {
bar="bar";
}
public void method() {
System.out.println(bar.length());
}
public static void main(String[] args) {
Base base=new Derived();
base.method();
}
}
On executing the code I got an exception:
Exception in thread "main" java.lang.NullPointerException
at Derived.method(Main.java:22)
at Base.<init>(Main.java:5)
at Derived.<init>(Main.java:17)
at Derived.main(Main.java:27)
I'm unable to understand why there is NullPointerException and the stackTrace of the exception. Anyone could help me to understand?
You can check the code here.
new Derived() creates a Derived object, which implies calling its super class constructor first, which in turn calls method - but you have overriden method so it is the child version of that method which is called. In that method, you call bar.length which has not been initialised yet.
Conclusion: it is almost never a good idea to call an overridable method in a constructor.
The code you have given is an antipattern. We should never invoke a method handling fields from a constructor for a simple reason that it might create unexpected results.
From your code, your are trying to initialize a field called bar in the Derived constructor. Now when you say Base b = new Derived(), the call happens in following fashion
Base static initializer -- If you have
Derived Static Initializer -- If you have
Base block initializer -- If you have
Base Constructor --> this is
the place you are calling method()
Derived Block initializer -- If you have
Derived constructor -->
this is the place where you are initializing bar
Now due to run time polymorphism, in to No. 4, when the Derived's method() gets called, the bar is not yet initialized to the value "bar" (since initialization happens at No. 6) , the NPE occurs
If I have a class:
class A {
public A() { }
}
and another
class B extends A {
public B() { }
}
is there any way to get B.B() not to call A.A()?
There is absolutely no way to do this in Java; it would break the language specification.
JLS 12 Execution / 12.5 Creation of New Class Instances
Just before a reference to the newly created object is returned as the result, the indicated constructor is processed to initialize the new object using the following procedure:
Assign the arguments for the constructor [...]
If this constructor begins with an explicit constructor invocation of another constructor in the same class (using this), then [...]
This constructor does not begin with an explicit constructor invocation of another constructor in the same class (using this). If this constructor is for a class other than Object, then this constructor will begin with an explicit or implicit invocation of a superclass constructor (using super).
Execute the instance initializers and instance variable initializers for this class [...]
Execute the rest of the body of this constructor [...]
The closest you can achieve to the desired behaviour is to delegate initialisation normally performed in the constructor to a template method, which you then override in your subclass implementation. For example:
public class A {
protected Writer writer;
public A() {
init();
}
protected void init() {
writer = new FileWriter(new File("foo.txt"));
}
}
public class B extends A {
protected void init() {
writer = new PaperbackWriter();
}
}
However, as other people have noted this can typically indicate a problem with your design and I typically prefer the composition approach in this scenario; for example in the above code you could define the constructor to accept a Writer implementation as a parameter.
Java deserialisation doesn't call the constructor, but it seems that it is based on some internal JVM tricks.
However, there is a framework that allows you to do that in a portable manner: Objenesis (http://www.theserverside.com/discussions/thread/44297.html)
I've seen this recently in Spring, when using CGLIB proxies, Spring creates two class instances, but the constructor is called only once: https://stackoverflow.com/a/11583641/2557118
This behavior is added in Spring 4:
CGLIB-based proxy classes no longer require a default constructor.
Support is provided via the objenesis library which is repackaged
inline and distributed as part of the Spring Framework. With this
strategy, no constructor at all is being invoked for proxy instances
anymore.
The possibility is that you can call the super class constructor of your choice. That is possible by calling the super class constructor explicitly as :
super(para_1, para_2,........);
class BaseA {
BaseA(){
System.out.println("This is BaseA");
}
BaseA(int a){
System.out.println("This is BaseA a");
}
}
class A extends BaseA {
A(){
super(5);
System.out.println("This is A");
}
public static void main(String[] args) {
A obj=new A();
}
}
Output will be:
This is BaseA a
This is A
No and if you could, your derived object wouldn't really be the object it's deriving from now would it? The is-a principle would be violated. So if you really need it, then polymorphism isn't what you're after.
Every superclass needs to be constructed and there is no other way then calling a constructor.
I think the only way to do it is messing up with the byte-code.
I'm not sure if the Classloader or the JVM checks if super() is being called, but, as Bozho wrote, you probably would end with inconsistent objects when doing so.
Nope - you cannot do it and why would you want to do it anyway? That would mess up your object model.
Anyways - i believe if you still want to do it and then you would have to manipulate the generated byte code.... there are a couple of libraries available that make it easy to instrument the byte code.
Strongly suggest against doing it...
Every object in java is a subclass of Object (object with a capital 'O'). when you create an object of a subclass the super class constructor is invoked. Even if your class is not inhereting anyother class, implicitly it is inheriting Object, so the Object constructor has to be called. So super() is invoked for this purpose.
Assuming you mean
class B extends A {
public B() { }
}
then sure you can
class B extends A {
public B() {
this(abort());
}
private B(Void dummy) {
/* super(); */
}
private static Void abort() {
throw null;
}
}
Not very useful. The interface [not Java keyword] to class A says that you need to run its constructor in order to construct it, not unreasonably. The exception is that serialisable classes are constructed without calling the constructors of the serialisable classes.
As pointed out by another poster, B doesn't extend A, so it won't call A's constructor anyways.
There is no way to do this in Java.
You can probably accomplish equivalently what you want to do as follows:
a) in each class of your hierarchy, include a constructor with a unique signature that calls the superclass's constructor with its arguments. For example, declare a class "Noop" and a constructor that takes that as an argument:
public class NoOp {
}
public class class1 {
class1() {
System.out.println("class1() called");
}
class1(String x, String y) {
System.out.println("class1(String, String) called");
}
class1(NoOp x) {
System.out.println("class1(NoOp) called");
}
}
public class class2 extends class1 {
class2() {
System.out.println("class2() called");
}
class2(String x, String y) {
System.out.println("class2(String, String) called");
}
class2(NoOp x) {
super(x);
System.out.println("class2(NoOp) called");
}
}
public class class3 extends class2 {
class3() {
System.out.println("class3() called");
}
class3(String x, String y) {
super(new NoOp());
System.out.println("class3(String, String) called");
}
class3(NoOp x) {
super(x);
System.out.println("class3(NoOp) called");
}
public static void main(String args[]) {
class3 x = new class3("hello", "world");
}
}
If you run this you will get the output
class1(NoOp) called
class2(NoOp) called
class3(String, String) called
So, effectively you have created a class3 constructor that only calls constructors that don't do anything.
I had a similar requirement where I needed my child class NOT to go through the super class' constructor, and I wanted the rest of the benefits of the super class. Since super class is also mine, here's what I did.
class SuperClass {
protected SuperClass() {
init();
}
// Added for classes (like ChildClassNew) who do not want the init to be invoked.
protected SuperClass(boolean doInit) {
if (doInit)
init();
}
//
}
class ChildClass1 extends SuperClass {
ChildClass1() {
// This calls default constructor of super class even without calling super() explicitly.
// ...
}
// ....
}
class ChildClass2 extends SuperClass {
ChildClass2() {
// This calls default constructor of super class even without calling super() explicitly.
// ...
}
// ....
}
class ChildClassNew extends SuperClass {
ChildClassNew() {
/*
* This is where I didn't want the super class' constructor to
* be invoked, because I didn't want the SuperClass' init() to be invoked.
* So I added overloaded the SuperClass' constructor where it diesn;t call init().
* And call the overloaded SuperClass' constructor from this new ChildClassNew.
*/
super(false);
//
// ...
}
// ....
}