📜  Java的非泛型与泛型集合

📅  最后修改于: 2021-09-14 02:42:21             🧑  作者: Mango

非泛型和泛型集合之间的差异

使用泛型的程序比非泛型代码有很多好处。

  1. 代码重用:通过使用泛型,只需编写一次方法/类/接口即可用于任何类型。而在非泛型中,代码需要在需要时一次又一次地编写。
  2. 类型安全:泛型在编译时比在运行时更容易出现错误(最好在编译时了解代码中的问题,而不是让代码在运行时失败)。

    例如:要创建一个存储学生姓名的 ArrayList,如果程序员错误地添加了一个整数对象而不是字符串,则编译器允许它。但是,当从 ArrayList 检索此数据时,它会在运行时导致非通用 ArrayList 出现问题。

    // A Simple Java program to demonstrate that NOT using
    // generics can cause run time exceptions
      
    import java.util.*;
      
    class Test {
        public static void main(String[] args)
        {
            // Creating an ArrayList without any type specified
            ArrayList al = new ArrayList();
      
            al.add("Sachin");
            al.add("Rahul");
            al.add(10); // Compiler allows this
      
            String s1 = (String)al.get(0);
            String s2 = (String)al.get(1);
      
            try {
                // Causes Runtime Exception
                String s3 = (String)al.get(2);
            }
            catch (Exception e) {
                System.out.println("Exception: " + e);
            }
        }
    }
    

    输出:

    Exception:
     java.lang.ClassCastException:
     java.lang.Integer cannot be cast to java.lang.String
    

    泛型如何解决这个问题:如果这个列表是泛型的,那么它将只需要 String 对象并在任何其他情况下抛出编译时错误。

    // Using generics converts run time exceptions into
    // compile time errors
      
    import java.util.*;
      
    class Test {
        public static void main(String[] args)
        {
            // Creating an ArrayList with String specified
            ArrayList al = new ArrayList();
      
            al.add("Sachin");
            al.add("Rahul");
      
            // Now Compiler doesn't allow this
            al.add(10);
      
            String s1 = al.get(0);
            String s2 = al.get(1);
            String s3 = al.get(2);
        }
    }
    

    输出:

    15: error: no suitable method found for add(int)
            al.add(10); 
              ^
    
  3. 不需要单独的类型转换:如果不需要泛型,那么,在上面的例子中,每次从 ArrayList 检索数据时,都需要对其进行类型转换。在每次检索操作中进行类型转换是一个令人头疼的问题。如果以某种方式已经知道列表仅包含字符串数据,则可以避免这种情况。

    例如:

    // A Simple Java program to demonstrate that
    // type casting is needed everytime in Non-Generic
      
    import java.util.*;
      
    class Test {
        public static void main(String[] args)
        {
            // Creating an ArrayList without any type specified
            ArrayList al = new ArrayList();
      
            al.add("Sachin");
            al.add("Rahul");
      
            // For every retrieval,
            // it needs to be casted to String for use
            String s1 = (String)al.get(0);
            String s2 = (String)al.get(1);
        }
    }
    

    泛型如何解决这个问题:如果这个列表是泛型的,那么它只需要 String 对象,并且在检索时只返回 String 对象。因此不需要单独的类型铸造。

    // A Simple Java program to demonstrate that
    // type casting is not needed in Generic
      
    import java.util.*;
      
    class Test {
        public static void main(String[] args)
        {
            // Creating an ArrayList with String specified
            ArrayList al = new ArrayList();
      
            al.add("Sachin");
            al.add("Rahul");
      
            // Retrieval can be easily
            // without the trouble of casting
            String s1 = al.get(0);
            String s2 = al.get(1);
        }
    }
    
  4. 实现泛型算法:通过使用泛型,可以实现适用于不同类型对象的算法,同时它们也是类型安全的。

有一些要点,它们将描述泛型和非泛型之间的区别:

Basis Non-generic Collection Generic Collection
Syntax ArrayList list = new ArrayList(); ArrayList list = new ArrayList();
Type-safety Can hold any type of data. Hence not type-safe. Can hold only the defined type of data. Hence type safe.
Type casting Individual type casting needs to be done at every retrieval. No type casting is needed.
Compile-Time Checking Checked for type safety at runtime. Checked for type safety at Compile-time.