Java 泛型:如何使编译器控制我放入构造函数的类型

Java 泛型:如何使编译器控制我放入构造函数的类型,java,generics,Java,Generics,此示例取自Java中的Thinking public class Automobile { } public class Holder<T> { private T a; public Holder(T a){ this.a = a; } public void set(T a){ this.a = a; } public T get(){ return a; } p

此示例取自Java中的Thinking

public class Automobile {
}

public class Holder<T> {
    private T a;
    public Holder(T a){
        this.a = a;
    }
    public void set(T a){
        this.a = a;
    }

    public T get(){
        return a;
    }

    public static void main(String[] args){
        Holder<Automobile> h = new Holder<Automobile>(new Automobile());
        Automobile a = (Automobile)h.get();
    }
}
因此,正如我所看到的,编译器不会控制我放入Holder对象的内容。好吧,那我就不懂泛型了。我有两个问题:

  • 使用它们的原因是什么?只是为了节省我把物体扔回汽车时的一些努力

  • 有没有办法让编译器控制我,让我真的把汽车放进支架里


  • 泛型的要点是编写可以包含或处理任何对象的数据结构。您可以在使用时指定它应该包含哪些类型的对象,例如:

    ArrayList<String> stringList = new ArrayList<String>();
    
    ArrayList stringList=新建ArrayList();
    
    (用于显示的Diamondoperator未简写)

    回答以下问题: 1:编写能处理所有对象(如集合)的代码,是的,编译器理解并能在编译时检查代码
    2:是的,不要使用泛型,而是为您的汽车编写代码规范

        Holder<Automobile> h = new Holder<Automobile>(new Automobile());
        Automobile a = (Automobile)h.get();
    
    Holder h = new Holder(new Automobile());
    Automobile a = (Automobile)h.get();
    

    这是自java 1.5及以上版本以来最好的方法:

    Holder<Automobile> h = new Holder<Automobile>(new Automobile()); //specify the generic parameter on both static and dynamic type
    Automobile a = h.get(); //no casting is necessary
    
    支架

    我甚至不确定如果没有泛型,这是否可行:

    因此,从技术上讲,泛型支持额外的特性,同时也鼓励类型安全性,从而减少代码错误,这总是很好的

    Integer a = new Integer(6);
    List<Integer> list = new ArrayList<Integer>();
    list.add(a);
    list.add("5"); //this will not compile -> you won't need to wait until runtime to see that things are incorrect!
    
    整数a=新整数(6);
    列表=新的ArrayList();
    列表.添加(a);
    列表。添加(“5”)//这将不会编译->您不需要等到运行时才能看到错误!
    
    “这是自java 1.5及以上版本以来最好的做事方式:“我不得不不同意。您使用的是原始类型构造函数,这是不安全的。正确的方法是
    Holder h=新的Holder(new Automobile())或(在Java 1.7+中<代码>支架h=新支架(新汽车())。使用原始类型构造函数可以关闭泛型类型检查。假设
    Holder
    的构造函数是
    publicholder(列表a)
    ,那么
    Holder h=newholder(newarraylist())将被允许,即使它显然是错误的。@newacct绝对正确!很抱歉出错了,显然构造函数参数把我搞砸了。固定的。我添加了两条注释,java 1.7,还修复了第三个代码段中的一个错误,请在编辑后检查答案
    
    Holder<Automobile> h = new Holder<Automobile>(new Automobile()); //specify the generic parameter on both static and dynamic type
    Automobile a = h.get(); //no casting is necessary
    
    Holder<Automobile> h = new Holder<>(new Automobile()); //diamond operator so you don't need to respecify the same thing
    Automobile a = h.get();
    
    Integer a = new Integer(6);
    List list = new ArrayList();
    list.add(a);
    list.add("5");
    for(int i = 0; i < list.size(); i++)
    {
        Integer integer = (Integer)list.get(i); //crashes at "5" which is String at runtime
        System.out.println(integer);
    }
    
    Integer a = new Integer(6);
    List<Integer> list = new ArrayList<Integer>();
    list.add(a);
    list.add("5"); //this will not compile -> you won't need to wait until runtime to see that things are incorrect!