我对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。 问题不在于哪种方法更好,而是导致上述行为的原因。
我已更新代码以反映托马斯的回答
答案 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()
即可获得正确的值