通用螺丝拧起无关的收集 [英] Generic screws up non-related collection

查看:127
本文介绍了通用螺丝拧起无关的收集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么与模板类无关的集合会放弃它们的类型?下面是一个例子:(对不起,它不会编译,因为我很困惑。)



import java.util.ArrayList;
import java.util.List;

public class TemplateTest {

public static class A {}

public static class B< T extends Comparable> {
列表< A> aList = new ArrayList< A>();

公开列表< A> getAList(){
返回aList;
}

public int compare(T t,T t1){
return t.compareTo(t1);



public static void main(String [] args){
B b = new B();
for(A a:b.getAList()){//这是行不通的

}
List< A> aList = b.getAList(); //此工程
for(A a:aList){

}
}
}
$ b

这段代码在编译时会抛出一个错误:

  test / TemplateTest。 java:24:incompatible types 
found:java.lang.Object
required:test.TemplateTest.A
for(A a:b.getAList()){

如果我指定 B 的模板,如 B< String> ,或者如果我完全从B中删除了模板,那么一切都可以。



发生什么事了?



编辑:人们指出没有必要使B通用,所以我加入B



问题部分在这里:


如果我指定t B的模板类似于 B ,或者如果我完全从B中删除
模板,那么一切都可以。


这不是一个选项,如果你想指定类型参数或者不指定你不选择。没有指定参数编译的唯一原因是为了向后兼容。编写缺少类型参数的新代码是一个编程错误。



List< A> list = b.getList()没有成功地解释类型,它只是有效地坚持在一个任意的转换中,并相信你的分配是正确的。如果你看看编译器警告,它实际上会产生一个不安全转换的警告。



for(A a:b.getList() ){} 将警告升级为错误,因为插入的转换将位于编译器生成的代码中,所以它拒绝自动生成不安全的代码,而不仅仅是发出警告。



从java语言规范:


原始类型的使用只允许作为让步兼容性
的遗留代码。
将通用性引入Java编程语言之后编写的代码中原始类型的使用是
强烈不鼓励。未来版本的Java
编程语言可能会禁止使用原始类型。


底线确实是Java泛型与C ++模板共享的唯一重要的东西是<>语法:)



更多信息:什么是原始类型,为什么我们不应该使用它? / a>


Why do collections that are not related to the template class drop their type? Here is an example: (Sorry, it will not compile because of the error I'm confused about.)

package test;

import java.util.ArrayList;
import java.util.List;

public class TemplateTest {

    public static class A { }

    public static class B<T extends Comparable> {
        List<A> aList = new ArrayList<A>();

        public List<A> getAList() {
            return aList;
        }

        public int compare(T t, T t1) {
            return t.compareTo(t1);
        }
    }

    public static void main(String[] args) {
        B b = new B();
        for (A a : b.getAList()) { //THIS DOES NOT WORK

        }
        List<A> aList = b.getAList(); //THIS WORKS
        for (A a : aList) {

        }
    }
}

This code throws an error upon compilation:

test/TemplateTest.java:24: incompatible types
    found   : java.lang.Object
    required: test.TemplateTest.A
        for (A a : b.getAList()) {

If I specify the template of B like B<String>, or if I remove the template from B completely, then everything is ok.

What's going on?

EDIT: people pointed out there was no need to make B generic so I added to B

解决方案

Yes, it is known behaviour that if you use a raw type, then all type parameters on the class are lost, not just the type-level parameter that you failed to declare.

The issue is partly here:

If I specify the template of B like B<String>, or if I remove the template from B completely, then everything is ok.

That's not an option, you aren't to choose if you want to specify the type parameter or not. The only reason it compiles at all with no parameter specified is for backward compatibility. Writing new code with missing type parameters is a programming error.

List<A> list = b.getList() does not successfully interpret the type, it is just effectively sticking in an arbitrary cast and trusting you that the assignment is correct. If you look at the compiler warnings it is in fact generating a warning for an unsafe conversion.

for(A a : b.getList()) {} upgrades that warning to an error because the inserted cast would be inside compiler generated code, so it refuses to auto-generate unsafe code at all, rather than just give a warning.

From the java language specification:

The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of genericity into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.

Bottom line really is that the only significant thing java generics share with C++ templates is the <> syntax :)

More details: What is a raw type and why shouldn't we use it?

这篇关于通用螺丝拧起无关的收集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆