Java中的泛型: Java泛型的详解

作者: Arvin Chen 分类: Java 来源: Break易站(www.breakyizhan.com)

Java中的泛型类似于C ++中的模板。我们的想法是允许类型(Integer,String,...等和用户定义的类型)成为方法,类和接口的参数。例如,像HashSetArrayListHashMap等类很好地使用泛型。我们可以将它们用于任何类型。

Java泛型的通用类

与C ++一样,我们使用<>在泛型类创建中指定参数类型。要创建泛型类的对象,我们使用以下语法:

//创建泛型类的实例 
BaseType <Type> obj = new BaseType <Type>()

注意:在参数类型中,我们不能使用像这样的原语
      'int','char'或'double'。
// A Simple Java program to show working of user defined
// Generic classes
  
// We use < > to specify Parameter type
class Test<T>
{
    // An object of type T is declared
    T obj;
    Test(T obj) {  this.obj = obj;  }  // constructor
    public T getObject()  { return this.obj; }
}
  
// Driver class to test above
class Main
{
    public static void main (String[] args)
    {
        // instance of Integer type
        Test <Integer> iObj = new Test<Integer>(15);
        System.out.println(iObj.getObject());
  
        // instance of String type
        Test <String> sObj =
                          new Test<String>("GeeksForGeeks"); 
        System.out.println(sObj.getObject());
    }
}

输出:

15
GeeksForGeeks

 

我们还可以在Generic类中传递多个Type参数。

// A Simple Java program to show multiple
// type parameters in Java Generics
 
// We use < > to specify Parameter type
class Test<T, U>
{
    T obj1;  // An object of type T
    U obj2;  // An object of type U
 
    // constructor
    Test(T obj1, U obj2)
    {
        this.obj1 = obj1;
        this.obj2 = obj2;
    }
 
    // To print objects of T and U
    public void print()
    {
        System.out.println(obj1);
        System.out.println(obj2);
    }
}
 
// Driver class to test above
class Main
{
    public static void main (String[] args)
    {
        Test <String, Integer> obj =
            new Test<String, Integer>("GfG", 15); 
 
        obj.print();
    }
}

输出:

GFG
15

Java泛型通用功能

我们还可以根据传递给泛型方法的参数类型编写可以使用不同类型的参数调用的泛型函数,编译器处理每个方法。

// A Simple Java program to show working of user defined
// Generic functions
  
class Test
{
    // A Generic method example
    static <T> void genericDisplay (T element)
    {
        System.out.println(element.getClass().getName() +
                           " = " + element); 
    }
  
    // Driver method
    public static void main(String[] args)
    {
         // Calling generic method with Integer argument
        genericDisplay(11);
  
        // Calling generic method with String argument
        genericDisplay("GeeksForGeeks");
  
        // Calling generic method with double argument
        genericDisplay(1.0);
    }
}

输出:

java.lang.Integer = 11
java.lang.String = GeeksForGeeks
java.lang.Double = 1.0

 

Java泛型的优点

使用泛型的程序比非泛型代码有许多好处。
代码重用:我们可以编写一个方法/类/接口,并用于我们想要的任何类型。

类型安全:泛型使错误显示在编译时而不是在运行时(在编译时知道代码中的问题总是更好,而不是在运行时使代码失败)。假设你想创建一个存储学生名字的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)
    {
        // Creatinga 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);
 
        // Causes Runtime Exception
        String s3 = (String)al.get(2);
    }
}

输出:

Exception in thread "main" java.lang.ClassCastException: 
   java.lang.Integer cannot be cast to java.lang.String
	at Test.main(Test.java:19)

Java泛型如何解决这个问题

在定义ArrayList时,我们可以指定此列表只能使用String对象。

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

输出:

15: error: no suitable method found for add(int)
        al.add(10); 
          ^

不需要单独类型转换:如果我们不使用泛型,那么,在上面的示例中,每次我们从ArrayList检索数据时,我们必须对其进行类型转换。在每次检索操作中进行类型转换都是一个令人头痛的问题。如果我们已经知道我们的列表只包含字符串数据,那么我们不需要每次都对它进行类型转换。

// We don't need to typecast individual members of ArrayList
import java.util.*;
 
class Test
{
    public static void main(String[] args)
    {
        // Creating a an ArrayList with String specified
        ArrayList <String> al = new ArrayList<String> (); 
 
        al.add("Sachin");
        al.add("Rahul");
 
        // Typecasting is not needed 
        String s1 = al.get(0);
        String s2 = al.get(1);
    }
}

实现通用算法:通过使用泛型,我们可以实现适用于不同类型对象的算法,同时它们也是类型安全的。

  •   本文标题:Java中的泛型: Java泛型的详解 - Break易站
    转载请保留页面地址:https://www.breakyizhan.com/java/5574.html
      微信返利机器人
      免费:淘宝,京东,拼多多优惠券
      腾讯,爱奇艺,优酷的VIP视频免费解析,免费看
      即刻扫描二维码,添加微信机器人!

    发表笔记

    电子邮件地址不会被公开。 必填项已用*标注