Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将对象列表强制转换为类列表';类型参数_Java_Eclipse_Generics_Casting - Fatal编程技术网

Java 将对象列表强制转换为类列表';类型参数

Java 将对象列表强制转换为类列表';类型参数,java,eclipse,generics,casting,Java,Eclipse,Generics,Casting,我试图理解看似相似的代码的不同编译结果。似乎可以将列表强制转换为列表,但前提是T不受具体类的限制。既然如此 List<Object> bis = new ArrayList<>(); 但是,这根本无法编译: public class Sandbox<T extends BigDecimal> { public static void main(String[] args) { new Sandbox<BigDecima

我试图理解看似相似的代码的不同编译结果。似乎可以将
列表
强制转换为
列表
,但前提是
T
不受具体类的限制。既然如此

List<Object> bis = new ArrayList<>();
但是,这根本无法编译:

    public class Sandbox<T extends BigDecimal> {

    public static void main(String[] args) {
        new Sandbox<BigDecimal>().foo();
    }

    private void foo() {    
        List<Object> bis = Arrays.asList(Integer.valueOf(1));
        List<T> result = (List<T>) bis;
        System.out.println(result);
    }

}
公共类沙箱{
公共静态void main(字符串[]args){
新沙盒().foo();
}
私有void foo(){
List bis=Arrays.asList(Integer.valueOf(1));
列表结果=(列表)bis;
系统输出打印项次(结果);
}
}
第9行中的编译器错误:无法将
List
强制转换为
List

那么这个
List bis=Arrays.asList(Integer.valueOf(1))显然无法编译,因为
数组.asList(Integer.valueOf(1))
将返回
列表
,这就是为什么您获取
时无法将列表强制转换为列表


第二种情况是,eclipse使用
T extensed CharSequence
进行了荒谬的编译,但我使用在线编译器进行了检查,它没有编译,所以很可能是eclipse错误

理解这种行为的关键是理解类型擦除的实际功能。尽管人们普遍认为它会在运行时删除类型参数,但实际上它并不是这样工作的。它的作用-它将它们减少到声明的参数边界。因此,无论您在哪里键入
List
,其中
T
有边界,它实际上都会减少到
List
。由于
对象
不是
字符序列
列表
不能强制转换为
列表
(因为它至少意味着
列表

为什么会发生这种情况?假设您的
沙盒
类具有接受T类型参数的方法:

public class Sandbox<T extends CharSequence> {
    void bar(T param) {
        //...
    }
}
因此它不能接受简单的
对象
。这就是为什么仅仅存在非空的下限参数限制了从

此外,通配符
类型参数可能会让您大吃一惊。它的意思是“我不知道它是什么,但我很确定它满足所有的限制”。非常奇怪,包括这一事实,你可以(几乎?)对它施放任何东西,所以这是可能的

  List<Object> bis = Arrays.asList(Integer.valueOf(1));
  List<T> result = (List<T>) (List<?>) bis;
List bis=Arrays.asList(Integer.valueOf(1));
列表结果=(列表)(列表)之二;

所以,当涉及到使用泛型设计类时,您应该非常非常小心。

需要更多的代码。您能给出您失败的确切行吗?将
列表
强制转换为
列表
是不安全的,其中
T
可以采用与
对象
不同的值。接口类型与类类型并不重要。是否有任何给定的Java编译器诊断该问题是另一个问题。
T extends CharSequence
版本不编译。好的,我接受
CharSequence
版本不能普遍编译。那么我应该责备Eclipse吗?;)在Eclipse下,只有一个警告,程序实际运行,只有在添加代码试图将列表元素强制转换为边界类型时才会失败。@gdabski有趣。在IntelliJ中,您可以切换编译器(我不知道eclipse),这是绝对正确的。它使用Eclipse编译器进行编译,但不使用javac。我怀疑这是Eclipse编译器中的一个bug。将
列表
强制转换为
列表
肯定是不正确的,因为
T扩展了CharSequence
,因为
对象
没有实现
CharSequence
,泛型也不是协变的。实际上,
List bis=Arrays.asList(Integer.valueOf(1))不编译。在java的早期版本中,它只会使用显式类型参数
List bis=Arrays.asList(Integer.valueOf(1))进行编译,但现在java已经改进了类型推断,并且它可以以任何一种方式工作。这是第一个答案,并提到Eclipse编译器行为不端,这似乎是我一直在寻找的结论,尽管最初我认为我不懂一些语言的本质@PaulBoddington也感谢您的宝贵意见。
public class Sandbox<T extends CharSequence> {
    void bar(T param) {
        //...
    }
}
 void bar(CharSequence param) {
     //...
 }
  List<Object> bis = Arrays.asList(Integer.valueOf(1));
  List<T> result = (List<T>) (List<?>) bis;