NullPointerException : Overriding constructor calling method of Base class in Derived class - java

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

Related

What will be the output of this code and how?

**Java code-MySuper class is the parent class and is extended by MySub class.I am creating the object MySub mySub = new MySub().I thought the output would be "y" but when I tried to run the code it was showing null as an output **
class MySuper {
String strl = "x";
public MySuper() {
myMethod();
}
void myMethod() {
System.out.print(strl);
}
}
class MySub extends MySuper {
String str2 = "y";
void myMethod() {
System.out.print(str2);
}
public static void main(String[] args) {
MySub mySub = new MySub();
}
}
The implicit constructor used by MySub looks like this:
class MySub extends MySuper {
String str2;
MySub() {
super();
str2 = "y";
}
// rest omitted for brevity
}
While inline field initialization is technically moved into the constructor, that's not necessarily important to know in and of itself. The important part is that the super constructor is invoked before the subclass's fields are initialized. So, when the super constructor invokes the myMethod() method, which is overridden by the subclass, the str2 field has not yet been assigned a non-default value. This results in your code printing out null.
And this is why you should avoid invoking overridable methods in a constructor.
This is due to Java dynamic method dispatch.
In your example. when you're instancing with the default constructor a MySub instance, this implicitly performs a call to the superclass' constructor. Within the superclass' constructor there is a call to myMethod() which is declared in MySuper and overridden in MySub.
Now, even if myMethod is being called from the superclass' constructor, which could fool us into thinking that the superclass' version of myMethod is being called, this is not what is actually happening.
The instance that is performing all these calls is still a MySub instance; therefore the myMethod implementation that is being invoked by Java is the closest implementation to MySub, i.e. the myMethod overridden by MySub.
So, if in this case the myMethod version that is being invoked in the superclass' constructor is the one overridden by MySub, why it's not printing str2 value? This is because, although method calls are dynamically dispatched, fields are statically dispatched. In Java, only methods can override their base class' methods. Child class' fields can only shadow base class' fields (with the same name). So Java already knows at compile time which fields are being used and only at run time which method implementations are being invoked. This means that when you're using a field in a child class, you can be sure that the one you're using is always the one you're referring to.
Getting back to your example, since myMethod is being invoked from the superclass' constructor, at this point we're still initializing the parent object, the child class' fields have not been initialized yet, they still contain their default values (the default value for references is null). So, in your dynamically dispatched myMethod we are printing the value of the statically dispatched str2 which is still at null because the child class initialization has not happened yet.
Minor Mistakes:
null output is coming because of extending the MySuper class and extending MySuper class is not required because the default class object can be created anywhere in a package without extending that.
You have not called the method myMethod() after creating the object mySub.That's why it is not printing the output as y.
Solution:
Try the code below, it is working smoothly.
class MySuper {
String strl = "x";
public MySuper() {
myMethod();
}
void myMethod() {
System.out.print(strl);
}
}
// class MySub extends MySuper {
class MySub {
String str2 = "y";
void myMethod() {
System.out.print(str2);
}
public static void main(String[] args) {
MySub mySub = new MySub();
// extra line added
mySub.myMethod();
MySuper ms=new MySuper();
}
}

Why does this.getClass give it's own class name rather than Anonymous class name?

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?

why overridden method calling from Subclass if i have done up-casting?

i have just started learning java::Inheritance and confused while mixing Up-Casting.
class Example{
public void methodOne(){
System.out.println("Example::Method_1");
}
public void methodTwo(){
System.out.println("Example::Method_2");
}
}
public class Test extends Example{
public void methodTwo(){ //Method overriding
System.out.println("Test::Method_2");
}
public void methodThree(){
System.out.println("Test::Method_3");
}
public static void main(String[] args){
Example exa = new Test(); // UpCasting
exa.methodOne(); // Printing Example::Method_1
exa.methodTwo(); // Printing Test::Method_2
// exa.methodThree(); // Error : can not find symbol
}
}
may someone please explain, what happening here??
When using inheritance, the compile-time type of the reference to an object on which you call a method is only used to see (at compile time) if the method may be invoked.
But at the invocation time, it does not matter what that compile-time type is. What really matters in this case is the runtime type of the object. It is Test, so the method is searched on Test first.
For methodOne() it is a bit different: it is not overriden by Test, so the version from its superclass (Example) is invoked.
Class Test extends Example and overrides the implementation of the methodTwo while adding new method methodThree. Now in you main
public static void main(String[] args){
Example exa = new Test(); // UpCasting
exa.methodOne(); // Printing Example::Method_1
exa.methodTwo(); // Printing Test::Method_2
// exa.methodThree(); // Error : can not find symbol
}
Static type of the variable exa is Example hence API usage bounded by public methods defined in Example class therefore it's illegal to call exa.methodThree() (not defined it Example).
While for methods which are define at Example class there is a dynamic binding at runtime, which leads to concrete implementation based on the reference pointed by exa variable. Therefore exa.methodTwo() call leads to execution of overrided function, since dynamic type is Test. And since Test doesn't override methodOne calling exa.methodOne() will lead to the implementation defined by Example.
if we create object of subclass and use reference of supper class then runtime time dynamic binding happens means at runtime java decides that which thing should get called.
in your case :
1. exa.methodOne(); methodOne belongs to super class and its not being overridden in child class so parent class method will be executed.
here if you create object like Test test = new Test(); then also test.methodOne() will give you the same result.
exa.methodTwo(); here methodTwo is being overridden in child class so at run time overridden method will get bonded and same will get executed.
in third case its giving error because you are using parent class reference but methodThree() is not part of parent so compile error is being thrown.
if wanna call third method then you can call like this : Test test = new Test(); test.methodThree()
FYI,
for safety we should always use #Override annotation in child call methods if we want to override any parent class method. it will help to avoid any method override glitches.

recursion with super keyword in java

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.

What's the difference between an instance initializer and a constructor?

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.

Categories