I'm getting NullPointerException whith below code.
Parent.java
public abstract class Parent {
public Parent(){
parentFunc();
}
public abstract void parentFunc();
}
Child.java
public class Child extends Parent {
ArrayList<String> list = new ArrayList<String>();
#Override
public void parentFunc() {
list.add("First Item");
}
}
when I create and instance of Child like new Child() I'm getting NullPointerException
Here is my console output
Exception in thread "main" java.lang.NullPointerException
at Child.parentFunc(Child.java:8)
at Parent.<init>(Parent.java:5)
at Child.<init>(Child.java:3)
at Main.main(Main.java:8)
I know that exception occurs because of Child.parentFunc() which called in parent constructor, but I really got confused. So I wonder what is going on
What is the order of creation;
When list variable is created
When constructors are called
When functions are created and called which called in constructors
When list variable is created?
It will be created once constructor of Child class runs.
When constructors are called?
When you try to make an object using new Child(), constructor is called for Child and it internally calls super() which calls the superclass constructor Parent().Note that the very first statement in Child() constructor is super().
The system will generate no-arguement constructor for you like this:
public child()
{
super();// calls Parent() constructor.
//your constructor code after Parent constructor runs
}
When functions are created and called which called in constructors
Clear out a bit what are you trying to ask .
Order Of Execution:
Parent Constructor->Child Constructor-->List
When parent constructor invoked the function called , You list not initialized and defailu value to the Object null is there,
#Override
public void parentFunc() {
list.add("First Item"); // list not yet initialized
}
You have an implicit Child() constructor. It calls Parent(), Parent() calls parentFunc() which is called in the sub-class. At that moment your list is still null and you get the NullPointerException (NPE).
See also:
Java Constructor and Field Initialization Order
It's usually a bad idea to call abstract methods from a constructor, as you exposed yourself to this kind of problem.
Related
I'm having issues understanding why this isn't working and how to solve it. I am trying to create an empty restaurantlist object in my constructor.
This is the problem below:
The RestaurantList class should be used to store all the Restaurant objects. This class should inherit from the LinkedList<
Restaurant> class.
The class needs to provide a default constructor that creates an empty RestaurantList object.
public class RestaurantList extends LinkedList<Restaurant> {
//Default constructor
public RestaurantList() {
RestaurantList rList = new RestaurantList();
}
Exception in thread "main" java.lang.StackOverflowError
You are calling the constructor of RestaurantList within the constructor of ResturantList. This will end up in creating infinite calls to this constructor.
The constructor is referencing itself in the constructor.
An empty constructor would return an empty RestaurantList object.
public RestaurantList() {}
You are recursively calling the constructor inside the constructor. Every time you do that, you're creating a new stack frame, and since the stack is not endless, while your code is, you end up overflowing the stack.
There's no sense in calling new RestaurantList() inside the constructor. Maybe you've meant to call the parent constructor using super()?
Just have a blank/empty constructor for RestaurantList(). Your implementation is currently recursive. Hence, the stackoverflow !
Thanks for the opportunity to answer about stackoverflow in Stackoverflow :-)
You can also do a static method to provide an instance.
public class MyClass {
..
..
public static MyClass getInstance() {
return new MyClass();
}
}
You would call it thus:
MyClass mc = MyClass.getInstance();
In Java, when a method is going to be executed, it's declaration is first searched for at the object's real class (that defines the real type of the object). If it's not found, then the superclass is checked. If isn't found there either, the next parent class is checked, and so on. However, look at the example below:
SuperClass s = new SubClass(list of parameter);
s.someMethodExistOnlyInSubClass();
This will give me a compile time error. I thought that, as mentioned above, it would first look for someMethodExistOnlyInSubClass() at SubClass, verify that it exists there and then execute it right away. If I use a variable of the type SuperClass to reference an instance of SubClass some parameters will go to SuperClass's constructor through a call to super() and the object will be instantiated there. In this context, to where have the remaining parameters gone?
By assigning a reference to an instance of SubClass to a variable of the type SuperClass, the variable is treated as if it were referencing an instance of SuperClass. Therefore, it will have no knowledge of any of the methods declared specifically in SubClass. Note, though, that the overrides performed in SubClass will still be effective.
In the context you described, to access someMethodExistOnlyInSubClass() you would have to cast s to the type SubClass. Look below:
((SubClass) s).someMethodExistOnlyInSubClass();
What you are trying to do will work only when the method is defined in both Parent class and subclass.
import java.util.*;
class Parent
{
public void sample()
{
System.out.println("Method of parent is getting Called");
}
}
class Subclass extends Parent
{
public void sample()
{
System.out.println("Method of Child class is getting Called");
}
}
public class Main
{
public static void main(String[] args){
Parent p = new Subclass();
p.sample();
}
}
OUTPUT : Method of Child class is getting Called
If the method exists only in Child class. You will have to create an instance of Child class itself.
Something like this :
import java.util.*;
class Parent
{
}
class Subclass extends Parent
{
public void sample()
{
System.out.println("Method of Child class is getting Called");
}
}
public class Main
{
public static void main(String[] args){
Subclass p = new Subclass();
p.sample();
}
}
Or you can type cast it as mentioned in the earlier post
Parent p = new Subclass();
((Subclass)p).sample();
An object is created based on its declaring class.
When you declare it as SuperClass s the object s wont have any method called someMethodExistOnlyInSubClass . So when you try to invoke this method, even before look at the subclass, you get a compile error.
The object s contrains only everything of the superclass, this object wont be aware of any subclass until u type cast the object to subclass.
if it is possible please make this sentence clear for me
here, the author said:
Do not call overridable methods from constructors. When creating a
subclass object, this could lead to an overridden method being called
before the subclass object is fully initialized. Recall that when you
construct a subclass object, its constructor first calls one of the
direct superclass’s constructors. If the superclass constructor
calls an overridable method, the subclass’s version of that method
will be called by the superclass constructor—before the subclass
constructor’s body has a chance to execute.
i can't understand that how it can be possible to call a subclass's version of the overridable method in the superclass's constructor
TnX
You have to first make a distinction between instantiation and initialization. Instantiation is the process of creating an instance of a type (allocating the space for it and getting a reference to that space). Initialization is the process of setting the state of the instance to its initial value.
Take the following type hierarchy:
class Foo {
public Foo() {}
}
class Bar extends Foo {
public Bar() {super();}
}
New instance creation expressions
new Bar();
cause instantiation and initialization. Instantiation happens first. Java creates an instance of concrete type Bar.
Then initialization needs to take place. In an inheritance hierarchy, the initialization follows the same hierarchy, but top to bottom.
Object
|
Foo
|
Bar
The constructor for Object runs first to initialize the state that is defined as part of Object, then the constructor for Foo is run to initialize the state that is defined as part of Foo and finally the constructor for Bar is run to initialize the state defined in Bar. Your instance is still of type Bar. So polymorphism still applies. If you invoke an instance method and that method is overriden somewhere lower in the hierarchy, that implementation will be invoked.
That's what that quote is referring to. It's dangerous. Read more here:
What's wrong with overridable method calls in constructors?
To illustrate the reason this is a bad idea with some (simplistic) code, consider these two classes:
class Greeter {
protected Greeter() {
printHello();
}
protected void printHello() {
System.out.println("Hello");
}
}
Looks simple enough, it prints Hello whenever you instantiate it. Now lets extend it:
class NamedGreeter extends Greeter {
private String name;
public NamedGreeter(String name) {
this.name = name;
}
#Override
protected void printHello() {
System.out.println("Hello " + name);
}
}
The intent is clearly to have the NamedGreeter greet you by name when instantiated, but in fact it will always print Hello null because the super constructor is called first when the NamedGreeter is instantiated.
Thanks to how polymorphism works, any time the printHello() method is called on a NamedGreeter (even if that call is from within the Greeter class) the implementation in NamedGreeter will be called. Calling that method from within the constructor of the parent class means that even if the child class extends it then no fields defined by the child will be initialized, simply because it's not possible to do anything in the child constructor (like initialize fields) before the parent constructor is called.
An example demonstrating that the child method will be invoked:
class Foo {
static class Parent {
Parent() {
someMethod();
}
void someMethod() {}
}
static class Child extends Parent {
#Override void someMethod() {
throw new AssertionError("Invoked");
}
}
public static void main(String[] args) {
new Child(); // Throws Exception.
}
}
Output:
Exception in thread "main" java.lang.AssertionError: Invoked
at Foo$Child.someMethod(Foo.java:16)
at Foo$Parent.<init>(Foo.java:9)
at Foo$Child.<init>(Foo.java:14)
at Foo.main(Foo.java:21)
public class Parent {
public void printParent()
{
System.out.println("I am the Parent");
System.out.println("----this is ::---" + this);
this.printChild();
}
private void printChild()
{
System.out.println("This is my child");
}
}
public class Child extends Parent {
private void printChild()
{
System.out.println("I am the child");
}
}
public class RelationshipTester {
#Test
public void testRelation()
{
Child parent = new Child();
parent.printParent();
}
}
This is the output :-
I am the Parent
----this is ::---datastructures.lists.inheritance.Child#1a692dec
This is my child
The object is of the type Child , yet it doesn't call the child method and the parent one. I have given this.printChild();
In the Parent class, you have declared printChild as private ... and called it. A private method cannot be overridden. Your printChild in the Child class is not known to the Parent class.
If you were to change the private modifier to public, then you would have an override, and your example should output what you are expecting.
Why won't Java let you override a private method? Well, basically, if you could do it then there would be no way to write a class with an abstraction boundary that a child class could not break. That would (IMO) be a major language design short-coming.
Why doesn't Java report an error or warning? Well there is no error because this is legal Java according to the JLS. As for a warning ... if you compile Parent in isolation there is no problem, because the code as written is declaring and using a private method. If you compile Child in isolation, the compiler can't see the private method in the Parent class. (Indeed, it may not even exist in the version of the .class file for Parent that you are compiling against.) Only if you compiled Parent and Child at the same time might the compiler spot something a bit odd.
The keyword 'this' point to the current class instance and here is the private void printChild(). And then you have created an object of class Child at RelationshipTester class. The scope of the two function is private which means to is bounded to that class only. Thus, it won't overwrite the subclass and would execute the Base class's method.
private methods are not inherited. When you call printParent, you're calling a method on Parent and when that method refers to this, it's referring to an instance of that class (Parent), which has its own printChild method. Making Parent#printChild a protected method should give the expected result.
public class Child extends Parent {
protected void printChild(){
System.out.println("I am the child");
}
}
use protected, not private
In this program we have to remember 2 points:
If we create an object for a subclass (here child) then memory also created for the super class. That means if the method that we are calling that is not found in the child class then Java Virtual Machine goes to parent class and checks for the method that we are calling and if the method is found it will execute. If the method is found in child class itself it will not go to the parent class.
private, static and final methods can't be overridden.
Since the scope of the method is private it is not visible to other class.
If I create an object of sub class then will the super class object also be created from which the sub class is inherited? If not then how by creating a sub class of Thread class (in multi-threading) calls the Thread class constructor and creates a Thread object?
An instance of the subclass is an instance of the superclass. Only one object is created, but as part of that creation, constructor calls are chained together all the way up to java.lang.Object. So for example:
public class Superclass {
// Note: I wouldn't normally use public variables.
// It's just for the sake of the example.
public int superclassField = 10;
public Superclass() {
System.out.println("Superclass constructor");
}
}
public class Subclass extends Superclass {
public int subclassField = 20;
public Subclass() {
super(); // Implicit if you leave it out. Chains to superclass constructor
System.out.println("Subclass constructor");
}
}
...
Subclass x = new Subclass();
System.out.println(x instanceof Subclass);
System.out.println(x instanceof Superclass);
System.out.println(x.superclassField);
System.out.println(x.subclassField);
The output of this is:
Superclass constructor
Subclass constructor
true
true
10
20
... because:
The first thing any constructor does is call either another constructor in the same class, or a superclass constructor. So we see "Superclass constructor" before "Subclass constructor" in the output.
The object we've created is (obviously) an instance of Subclass
The object we've created is also an instance of Superclass
The single object we've created has both fields (superclassField and subclassField). This would be true even if the fields were private (which they usually would be) - the code in Subclass wouldn't be able to access a private field declared in Superclass, but the field would still be there - and still accessible to the code within Superclass.
The fact that we've got a single object with all the state (both superclass and subclass) and all the behaviour (any methods declared within Superclass can still be used on an instance of Subclass, although some may be overridden with more specializd behaviour) is crucial to understanding Java's approach to polymorphism.
Youre only creating one object when you create a subclass of another. It is an instance of both the subclass and all its parents. Example, I create a cat object. It is a cat, and at the same time a feline, mammal, and animal, and an Object.
When you create an object, it gets one piece of memory with one set of variables to hold the all of its data.
The subclass will contain fields from the child and any fields from its ancestors. So it's a single object that acts like the child and its ancestors. There is no parent class object created when you create a subclass.
No there Is only one Object there. There Is a misconception that constructor is for creating an object. But It actually for initializing an object. So when we created child class object along with the child class constructor the parent class constructor also executed because of the first line of the child class constructor either this() or super(). Now, look at the following code.
Public class P{
public P(){
System.out.println(this.hashCode()); // Parent class Constructor
}
}
public class C extends P{
public C(){
System.out.println(this.hashCode()); // Child Class constructor
}
}
public class Test{
public static void main(String [] args){
C c = new C();
System.out.println(c.hashCode());
}
}
If you run the code you can see There is only one HashCode. and an object just has one hashCode. If the parent class object would be created then there must be another hashCode for that object.
Here I am abbreviating with an example that
If a child class object is created, does it automatically create super class object?
class P{
P(){
System.out.println(this.hashCode()); // it will print 2430287
}
}
class C extends P{
C(){
System.out.println(this.hashCode()); // it will also print 2430287
}
}
public class Test{
public static void main(String... args){
C obj = new C();
System.out.println(c.hashCode()); //Again, it will print 2430287
}
}
If you compile and run this code you will find same Object hashCode is getting printed. So, this means there is only one object is created.
Now, how is the parent class object being initialized?
In this example only one object is created which is an instance of the child class, but there are two constructors (parent and child) being executed. But the constructor are just in context of child class only.
Nope.
It will not create instance of parent class. But certainly it will create an instance.And the object reference passed to child class. Hence instance is created at parent class and invoked by child class constructor. and child class methods operates.