在Java中,<T>(尖括号)代表什么意思?

165

我目前正在学习Java,最近遇到了尖括号(<>)的问题。它们到底是什么意思?

public class Pool<T>{
    public interface PoolFactory<T>{
        public T createObject();
    }
    this.freeObjects = new ArrayList<T>(maxsize)
}

<T>是什么意思?这意味着我可以创建一个类型为T的对象吗?


4
我发现你的代码很难解析。首先没有缩进,有两个左花括号但只有一个右花括号。T createObject 应该在 Pool 还是 PoolFactory 内部? this.freeObjects = ... 应该放在哪里?这是一个单独的示例吗?将其放在那里是非法的,它必须在方法内部。 - mgiuca
1
如果有人想了解关于<>(钻石操作符)的信息,例如可以在以下语句中使用: List<Integer> list = new ArrayList<>(); 请访问https://docs.oracle.com/javase/7/docs/technotes/guides/language/type-inference-generic-instance-creation.html。 - Pshemo
6个回答

191

<T>是一个通用类型,通常可以理解为“类型T”。它实际上取决于<>左边的类型。

我不知道PoolPoolFactory是什么,但您也提到了ArrayList<T>,这是一个标准的Java类,因此我会谈到它。

通常情况下,您不会在其中看到“T”,而是会看到另一种类型。例如,如果您看到ArrayList<Integer>,那就意味着“一个由整数组成的ArrayList”。许多类使用泛型来约束容器中元素的类型,例如HashMap<String,Integer>,表示“具有String键和Integer值的映射”。

您的Pool示例略有不同,因为在这种情况下,您正在定义一个类。因此,在那种情况下,您正在创建一个类,其他人可以用特定类型替换T来实例化该类。例如,我可以使用您的类定义创建一个类型为Pool<String>的对象。这将意味着两件事:

  • 我的Pool<String>将具有接口PoolFactory<String>,其中包含一个返回StringcreateObject方法。
  • 在内部,Pool<String>将包含一个字符串的ArrayList

这是个好消息,因为在另一个时间,我可以创建一个Pool<Integer>,它将使用相同的代码,但在源代码中看到T的地方使用Integer


3
迄今为止我看过的最好的解释 :) 非常感谢! - Suhas Chikkanna

46

这很简单。这是在J2SE 5中引入的新功能。在类名后指定尖括号意味着您正在创建一个临时数据类型,可以保存任何类型的数据。

例如:

class A<T>{
    T obj;
    void add(T obj){
        this.obj=obj;
    }
    T get(){
        return obj;
    }
}
public class generics {
    static<E> void print(E[] elements){
        for(E element:elements){
            System.out.println(element);
        }
    }

    public static void main(String[] args) {
        A<String> obj=new A<String>();
        A<Integer> obj1=new A<Integer>();
        obj.add("hello");
        obj1.add(6);
        System.out.println(obj.get());
        System.out.println(obj1.get());

        Integer[] arr={1,3,5,7};
        print(arr);
    }
}

你可以用任何名称代替<T>,它们的作用是相同的。试试在<T>的位置上写入<ABC>

这只是为了方便:

  • <T>表示任何类型
  • <E>表示元素类型
  • <N>表示数字类型
  • <V>表示值
  • <K>表示键

但你可以随意更改名称,这并不重要。

此外,IntegerStringBoolean等都是Java的包装类,可以在编译期间帮助检查类型。例如,在上面的代码中,objString类型,因此你不能向其添加其他类型(尝试obj.add(1),会出现错误)。同样,obj1Integer类型,你不能向其添加其他类型(尝试obj1.add("hello"),会出现错误)。


26

这与Java中的泛型有关。如果我提到 ArrayList<String>,那意味着我只能向该ArrayList添加String类型的对象。

Java中泛型的两个主要好处是:

  1. 减少程序中的强制转换次数,从而减少程序中潜在的错误数量。
  2. 提高代码清晰度

12

被称为通用类型。您可以像这样实例化一个对象池:

PoolFactory<Integer> pool = new Pool<Integer>();

泛型参数只能是引用类型。因此,您不能使用像int、double、char或其他原始数据类型。


9

<>用于表示Java中的泛型

在此示例中,T是类型参数。但是,不要误解:实例化是您无法使用T执行的少数几件事之一。

除了上面链接的教程外,Angelika Langers Generics FAQ也是该主题的绝佳资源。


8

泛型类是一种在创建时以数据类型作为参数的类。这个类型参数使用尖括号指定,每次实例化类时都可以更改类型。例如,我们可以创建一个用于员工对象的ArrayList和另一个用于公司对象的ArrayList。

ArrayList<Employee> employees = new ArrayList<Employee>();
ArrayList<Company> companies = new ArrayList<Company>();

您会注意到我们使用相同的ArrayList类来创建两个列表,并使用尖括号传递Employee或Company类型。一个通用类可以处理多种数据类型,从而减少了执行类似任务的许多类。

泛型还通过为所有内容提供强类型来帮助减少错误,这有助于编译器指出错误。通过为ArrayList指定类型,如果您尝试将Employee添加到Company列表中或反之亦然,编译器将引发错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接