Java 试图理解泛型

Java 试图理解泛型,java,generics,arraylist,Java,Generics,Arraylist,我有下面的代码 public static void main(String[] args) { ArrayList<Integer> iList = new ArrayList(); iList = returList(); for (int i = 0; i < iList.size(); i++) { System.out.println(iList.get(i)); } }

我有下面的代码

public static void main(String[] args) {
        ArrayList<Integer> iList = new ArrayList();
        iList = returList();
        for (int i = 0; i < iList.size(); i++) {
            System.out.println(iList.get(i));
        }
    }

    public static ArrayList returList() {
        ArrayList al = new ArrayList();
        al.add("S");
        al.add(1);
        return al;
    }
publicstaticvoidmain(字符串[]args){
ArrayList iList=新的ArrayList();
iList=returList();
对于(int i=0;i
现在,我的问题是为什么Arraylist接受在“Arraylist iList=new Arraylist();”行中创建原始Arraylist对象而同样的情况下,甚至从方法调用返回偶数


现在,哪种类型的数据将会存在,泛型意味着什么?我没有看到编译错误,而且这段代码运行得很好。

因为它是错误的。这是正确完成的方式:

public static void main(String[] args) {
    List<Integer> iList = returList();
    for (int i = 0; i < iList.size(); i++) {
        System.out.println(iList.get(i));
    }
}

public static List<Integer> returList() {
    List<Integer> al = new ArrayList<Integer>();
    //al.add("S"); This line can't compile now!
    al.add(1);
    return al;
}
publicstaticvoidmain(字符串[]args){
List iList=returList();
对于(int i=0;i
注意事项:

  • 针对接口编程
  • 避免不必要的初始化
  • 在实现中也使用类型参数(赋值运算符的RHS)

  • 因为这是错误的。这是正确完成的方式:

    public static void main(String[] args) {
        List<Integer> iList = returList();
        for (int i = 0; i < iList.size(); i++) {
            System.out.println(iList.get(i));
        }
    }
    
    public static List<Integer> returList() {
        List<Integer> al = new ArrayList<Integer>();
        //al.add("S"); This line can't compile now!
        al.add(1);
        return al;
    }
    
    publicstaticvoidmain(字符串[]args){
    List iList=returList();
    对于(int i=0;i
    注意事项:

  • 针对接口编程
  • 避免不必要的初始化
  • 在实现中也使用类型参数(赋值运算符的RHS)

  • 创建泛型是为了帮助开发人员,但是为了从中受益,您必须使用泛型。您的IDE将警告您对ArrayList的原始使用:

    ArrayList is a raw type. References to generic type ArrayList<E> should be parameterized
    
    ArrayList是原始类型。对泛型类型ArrayList的引用应参数化
    
    但这并不能阻止你挂断自己,不。请注意,在某些IDE中,你实际上可以强制这些是编译错误,这可能就是你正在寻找的

    现在,就你清单上的内容而言,它正是你放在清单上的内容。请记住,泛型只不过是“语法糖”,即从生成的类中完全删除的编译器提示。因此,在运行时,没有指示对象的泛型类型。在您的情况下,您的代码运行良好,因为您所做的只是打印列表内容。您的所有对象都将自动转换为字符串!尝试以下方法,获得一些乐趣和游戏:

    public static void main(String[] args) {
            ArrayList<Integer> iList = new ArrayList();
            iList = returList();
            for (final Integer i: iList) {
                System.out.println(i.intValue());
            }
    }
    
    publicstaticvoidmain(字符串[]args){
    ArrayList iList=新的ArrayList();
    iList=returList();
    for(最终整数i:iList){
    System.out.println(i.intValue());
    }
    }
    
    创建泛型是为了帮助开发人员,但您必须使用它们才能从中获益。您的IDE将警告您对ArrayList的原始使用:

    ArrayList is a raw type. References to generic type ArrayList<E> should be parameterized
    
    ArrayList是原始类型。对泛型类型ArrayList的引用应参数化
    
    但这并不能阻止你挂断自己,不。请注意,在某些IDE中,你实际上可以强制这些是编译错误,这可能就是你正在寻找的

    现在,就你清单上的内容而言,它正是你放在清单上的内容。请记住,泛型只不过是“语法糖”,即从生成的类中完全删除的编译器提示。因此,在运行时,没有指示对象的泛型类型。在您的情况下,您的代码运行良好,因为您所做的只是打印列表内容。您的所有对象都将自动转换为字符串!尝试以下方法,获得一些乐趣和游戏:

    public static void main(String[] args) {
            ArrayList<Integer> iList = new ArrayList();
            iList = returList();
            for (final Integer i: iList) {
                System.out.println(i.intValue());
            }
    }
    
    publicstaticvoidmain(字符串[]args){
    ArrayList iList=新的ArrayList();
    iList=returList();
    for(最终整数i:iList){
    System.out.println(i.intValue());
    }
    }
    
    答案如下:

    为什么允许使用原始类型?

    原始类型 允许使用的语言主要是为了方便接口 使用非通用(遗留)代码

    例如,如果您有一个非泛型遗留方法,该方法将列表作为 参数时,可以将参数化类型(如List)传递给 这种方法。相反,如果您有一个返回列表的方法, 可以将结果分配给列表类型的引用变量 ,前提是您知道返回的列表确实是 字符串列表

    答案是:

    为什么允许使用原始类型?

    原始类型 允许使用的语言主要是为了方便接口 使用非通用(遗留)代码

    例如,如果您有一个非泛型遗留方法,该方法将列表作为 参数时,可以将参数化类型(如List)传递给 这种方法。相反,如果您有一个返回列表的方法, 可以将结果分配给列表类型的引用变量 ,前提是您知道返回的列表确实是 字符串列表


    阅读此文:,建议阅读两到三次。

    阅读此文:,建议阅读两到三次。

    一点泛型的历史可能有助于解释一些奇怪之处

    当泛型最初被提出用于Java时,假设必须在不改变底层.class格式的情况下引入更改。因此泛型被实现为原始类型上的一个薄层。一种称为类型擦除的技术成为了解决方案。这意味着编译器将删除所有泛型