为什么属性为子类返回null

时间:2017-05-04 08:51:40

标签: java

我对Java相对较新。我有一个问题,我无法弄明白。

我有一个抽象类(超类),带有属性,类型。

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;
    }

}

然后我有一些类型的子类:

public class NumberVariable extends Variable {

    public int value;

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

}

我想使用type属性来获取对象的实例(这里是NumberType()。这是Type的子类。) 无论如何,当我打印这个:

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

我试图弄清楚var.type为什么不返回NumberType对象。 我试图解决的问题是: 我需要做一些类型检查,需要比较2个对象,看看它们是否具有相同的类型(相同的Type对象而不是Java类型)。 上面方法背后的想法是我可以从对象的属性中获取Type对象,然后比较它们。 我也尝试过创建一个方法(在Variable Subclass上实现):

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

然而,这也会打印出来。

编辑: 关于同时具有type属性和getType()方法似乎存在一些混淆。 原因如下: 它们并不意味着两者都存在。它们并不意味着相关。 这是我尝试过的两种方法,但都返回null。 问题不在于哪种方法更好,而是导致上述行为的原因。

我已更新代码以反映托马斯的回答

3 个答案:

答案 0 :(得分:1)

在你的超类中你有这个:

public Type type;
public abstract Type getType();

这意味着getType()是一个抽象方法,没有任何实现,根本没有type的关系(除了名称中的相似之处)。

在您的子类中,然后实现该抽象方法,并在每次调用时返回相应类型的新实例:

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

再次与type无关,因此var.type仍为空。

由于您已经将类型传递给构造函数,因此您可能希望在超类中的getType()实现中创建:

public Type getType() {
  return type;
}

并删除子类中的重写实现。

另请注意,即使System.out.println(var.type);不为空,null仍可能会打印type。这是因为在toString()上调用了type,如果你重写了该方法以返回null,那么你将获得null。

执行此操作的指标是System.out.println(var.type.getClass());不会抛出NullPointerException

答案 1 :(得分:0)

您应该根据您的要求使用comprator或者类似的。这两个是在迭代情况下比较任何对象的最佳方法。 java 8中有很多实用程序类用于压缩。 看下面的代码我做了什么工作稍微调整是必要的,它是: - )

<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 {
}

答案 2 :(得分:0)

来自您的代码评论:

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

我可以向你保证var.type。它不是null,因为JVM实际上会调用var.type.toString()来打印实例值。因此,如果您检查此实例,则会看到覆盖toString()的重叠null

我怎么能确定,你在第二行没有得到NullPointerException,在空实例上调用.getClass()会抛出运行时异常,你的代码不会# 39;吨

只需更新Type.toString()或子类NumberType.toString()即可获得正确的值