Sha*_*vil 2 java generics abstract-class casting
我有一个带有抽象类的Java枚举,如下所示:
public enum Strategy {
STRING {
@Override
public String execute() {
return "ABCDE";
}
},
INTEGER {
@Override
public Integer execute() {
return 12345;
}
};
public abstract Object execute();
}
Run Code Online (Sandbox Code Playgroud)
当我使用它时,我希望能够这样做:
String text = Strategy.STRING.execute();
Integer num = Strategy.INTEGER.execute();
Run Code Online (Sandbox Code Playgroud)
但是,我的IDE警告我,这些是不兼容的类型,不会编译.要解决它,我必须改为:
String text = (String) Strategy.STRING.execute();
Integer num = (Integer) Strategy.INTEGER.execute();
Run Code Online (Sandbox Code Playgroud)
我宁愿不必投出我的execute()方法的结果.有没有办法返回具体方法签名中指定的类型,而不是返回Object?
覆盖方法时,可以声明子类方法以返回超类返回类型的细化.但是,调用超类方法的代码无法知道返回对象的实际类型.在你的情况下,它只知道它Object是某种形式.这就是为什么你必须在分配给一个更具体的变量之前进行转换.
枚举对象有点奇怪.编译此代码时:
Strategy.STRING.execute();
Run Code Online (Sandbox Code Playgroud)
编译器生成此字节码(输出自javap -c):
getstatic #2 // Field Strategy.STRING:LStrategy;
invokevirtual #3 // Method Strategy.execute:()Ljava/lang/Object;
Run Code Online (Sandbox Code Playgroud)
如您所见,它将其视为Strategy.STRING类的静态字段Strategy,并且该字段属于类型Strategy.因此,尽管出现了,但调用代码并不知道它正在调用它的STRING版本execute().
不过,我想知道你为什么要这么做.设计需要强制转换的API似乎与面向对象编程的精神背道而驰.