Java 返回显式声明的超类的子类的泛型方法
目标 标题又长又混乱。。。我想要一种可以这样使用的方法:Java 返回显式声明的超类的子类的泛型方法,java,generics,Java,Generics,目标 标题又长又混乱。。。我想要一种可以这样使用的方法: Double d = getAsNumber(Double.MAX_VALUE); Short s = getAsNumber(Short.MAX_VALUE); 该方法保证只接受java.lang.Number的子类 该方法将只返回传入的完全相同类的实例 传入的参数实际上是一个默认值,以防getAsNumber方法实际上没有值 到目前为止我拥有的 这实际上是可行的,但它很难看,我不明白为什么我需要显式地使用(t)进行强制转换。en
Double d = getAsNumber(Double.MAX_VALUE);
Short s = getAsNumber(Short.MAX_VALUE);
- 该方法保证只接受java.lang.Number的子类
- 该方法将只返回传入的完全相同类的实例
private enum NUMBER_CLASS {
Double, Float, Integer, Long, Short
}
private static final <T extends Number> T getAsNumber( T defaultVal ) {
final String string = "2";//would normally get from data source
if (string==null) {
return defaultVal;
}
NUMBER_CLASS numberClass = NUMBER_CLASS.Double.valueOf(defaultVal.getClass().getSimpleName());
switch (numberClass) {
case Double:
return (T) Double.valueOf(string); // WHY is explicit cast necessary!
case Long:
return (T) Long.valueOf(string);
default:
throw new IllegalArgumentException("Must give a java.lang.Number");
}
}
私有枚举数\u类{
双精度、浮点、整数、长、短
}
私有静态最终T getAsNumber(T defaultVal){
final String=“2”//通常从数据源获取
if(字符串==null){
返回defaultVal;
}
NUMBER_CLASS numberClass=NUMBER_CLASS.Double.valueOf(defaultVal.getClass().getSimpleName());
开关(numberClass){
双格:
return(T)Double.valueOf(string);//为什么需要显式强制转换!
案例长度:
返回(T)长。值(字符串);
违约:
抛出新的IllegalArgumentException(“必须给出java.lang.Number”);
}
}
一定有更好的办法吗?
**更新**
这里提出了多个问题。我实际上想问的主要问题是为什么我需要显式地使用(T)进行强制转换。在我看来,编译器拥有保证Double满足方法签名返回类型所需的所有信息。编译器无法找到函数的内部推理。想象一下代码:
switch (numberClass) {
case Double:
return Long.valueOf(string); // If there is no cast it will broke type system
case Long:
return Double.valueOf(string); // The same
default:
throw new IllegalArgumentException("Must give a java.lang.Number");
}
返回值未正式连接到类型
t
,因此,如果没有强制转换,则可以使用双参数等返回Long
。这就是需要强制转换的原因。编译器无法找到函数的内部推理。想象一下代码:
switch (numberClass) {
case Double:
return Long.valueOf(string); // If there is no cast it will broke type system
case Long:
return Double.valueOf(string); // The same
default:
throw new IllegalArgumentException("Must give a java.lang.Number");
}
返回值没有正式连接到类型t
,因此没有强制转换,就可以使用Double
参数等返回Long
。这就是需要强制转换的原因。没有更好的方法。在Java中泛化Number
类型不可避免地会失败。(试着做你想做的转换课程也不可避免地会像你一样尴尬。)这是公平的,我承认我问了很多问题。。。不过,我有一个优先考虑的问题——为什么我需要明确的演员阵容?我想这是在学习。我将更新这个问题。Java中没有任何机制可以让编译器判断您已经“证明”T
是任何特定类型。这不是Java的类型系统知道如何做的事情。那么我键入“”的值是什么呢?这不是说返回实例将是Number的实例吗?我们知道编译器可以测试Double是Number的子类-它会不断地进行这种类型的测试。你不能告诉编译器你已经知道了Number的子类是哪个。没有更好的方法了。在Java中泛化Number
类型不可避免地会失败。(试着做你想做的转换课程也不可避免地会像你一样尴尬。)这是公平的,我承认我问了很多问题。。。不过,我有一个优先考虑的问题——为什么我需要明确的演员阵容?我想这是在学习。我将更新这个问题。Java中没有任何机制可以让编译器判断您已经“证明”T
是任何特定类型。这不是Java的类型系统知道如何做的事情。那么我键入“”的值是什么呢?这不是说返回实例将是Number的实例吗?我们知道编译器可以测试Double是Number的子类-它经常进行这种类型的测试。你不能告诉编译器你已经知道了Number的子类是哪个。