DJESMOND
DJESMOND

Reputation: 3

Why does property return null for subclass

Im relatively new to Java. I have an issue i cant quite figure out.

I have an abstract class (the super class), with a property, type.

public abstract class Variable implements ICompilerObject {

    public String id;
    public Type type;

    public Type getType() {
        return type;
    }

    public Variable(String name, Type t){
        this.id = name;
        type = t;
    }

}

I then have some subclasses of type:

public class NumberVariable extends Variable {

    public int value;

    public NumberVariable(String name){
        super(name, new NumberType());
    }

}

I want to use the type property to get an instance of an object (here it is NumberType(). which is a sublclass of Type.) Howeever when i print this:

Variable var = someFunctionThatGetsAVariableFromList(); 
// var is now a NumberVariable with type == new NumberType();
System.out.println(var.type); //Prints null
System.out.println(var.type.getClass()); 
//Prints class compilerObjects.types.NumberType

Im trying to figure why var.type doesn't return the NumberType object. The problem im trying to solve is: I need to do some type checking, where 2 objects needs to be compare, to see if they have the same type (that being the same Type object and NOT Java types). The idea behind the approach above is that i can get the Type object from the property of the object and then compare those. I have also tried creating a method instead (implemented on the Variable Subclass):

@Override
public Type getType() {
    return new NumberType();
}

However this also prints null.

EDIT: There seems to be some confusion about having both a type property and a getType() method. Here is the reason: They are NOT meant to both be present. They are NOT meant to be related. This is the two approaches i have tried, but both return null. The question is not around which approach is better, but rather what causes the mentioned behaviour.

I have updated the code to reflect Thomas's answer

Upvotes: 0

Views: 1081

Answers (3)

Kanthishere
Kanthishere

Reputation: 169

You should use comprator or comparable as per your requirement. these two are best approaches to compare any object in case iterations. There are lot many utility class in java 8 for compression. see below the code what i did which is working a little bit tweaking is required thats it :-)

<pre>
    package stackoverflowquestions;

    import java.util.ArrayList;
    import java.util.List;

    public class NumberVariable extends Variable {
        public int value;

        @Override
        public Type getType() {
            return new NumberType();
        }

        public NumberVariable(String name) {
            super(name, new NumberType());
        }

        public static void main(String[] args) {
            Variable variable = someFunctionThatGetsAVariableFromList();
            System.out.println(variable.type); // Prints null
            System.out.println(variable.type.getClass());
        }
        private static Variable someFunctionThatGetsAVariableFromList() {
            List<Variable> vl = new ArrayList<Variable>();

            Variable variable = new NumberVariable("new Object");
            vl.add(variable);
            return vl.get(0);
        }

    }
    abstract class Variable implements ICompilerObject {
        public String id;
        public Type type;

        public Variable(String name, Type t) {
            this.id = name;
            this.type = t;
        }
        public abstract Type getType();}

class Type {

}
class NumberType extends Type {

}
interface ICompilerObject {
}

Upvotes: 0

AxelH
AxelH

Reputation: 14572

From your code's comment:

System.out.println(var.type); 
//Prints null
System.out.println(var.type.getClass()); 
//Prints class compilerObjects.types.NumberType

I can assure you that var.type. It is not null because the JVM will actually call var.type.toString() to print the instance value. So if you check this instance, you should see an override of toString() returning null.

How can I be sure, well you don't get a NullPointerException on the second line, a call of .getClass() on a null instance would throw a runtime exception, your code don't.

Just update Type.toString() or the subclass NumberType.toString() to get the correct value

Upvotes: 0

Thomas
Thomas

Reputation: 88707

In your superclass you have this:

public Type type;
public abstract Type getType();

That means that getType() is an abstract method without any implementation and no relation to type at all (except for similarities in name).

In your subclass you then implement that abstract method and return a new instance of the corresponding type on every call:

public Type getType() {
  return new NumberType();
}

Again there's no relation to type and hence var.type will still be null.

Since you're already passing the type to the constructor you probably want to create in implementation of getType() in your superclass:

public Type getType() {
  return type;
}

and remove the overriding implementation in your subclasses.

Also note that System.out.println(var.type); might still print null even if type is not null. That's because toString() is called on type and if you've overridden that method to return null you'll get null.

An indicator for you doing this is that System.out.println(var.type.getClass()); doesn't throw a NullPointerException.

Upvotes: 1

Related Questions