我对ArrayLists和泛型有点困惑,例如,在我声明的下面的程序中,Gen<Integer>iOb=new Gen<Integer>(88);
它声明了一个通用类型的Integer是否正确?但是,如果我以同样的方式宣布一个arraylist?在arraylist的情况下,它是尖括号中的类型,但是,研究泛型,它说尖括号中的类型是泛型类型?我如何知道它是类型类型的通用列表还是泛型?
//A simple generic class
//Here, T is a type parameter that
///will be replaced by a real type
//when an object of type gen is created
class Gen<T> {
T ob;//declare an object of type T
//Pass the constructor a refernce to
//an object of type T
Gen(T o) {
ob = o;
}
//return ob
T getob() {
return ob;
}
//show type of t
void showType() {
System.out.println("Type of T is " + ob.getClass().getName());
}
}
class GenDemo {
public static void main(String[] args) {
//create a gen reference for integers
Gen<Integer> iOb;
//Create a Gen<Integer>Object and assign its
//reference to iob, notice the use of autoboxing
//to encapsulate the value 88 within an integer object
iOb = new Gen<Integer>(88);
//show the type off data used by iob
iOb.showType();
//get the value in Iob notice that no cast is needed
int v = iOb.getob();
System.out.println("Value: " + v);
System.out.println();
//create a gen object for strings
Gen<String> strOb = new Gen<String>("Generic Test");
//show the type of data
strOb.showType();
//get the value of strOb, again notice that no cast is needed
String str = strOb.getob();
System.out.println("Value :" + str);
}
}
答案 0 :(得分:4)
您似乎混淆了 泛型类型 和 类型参数 的概念。
鉴于你的课程:
class Gen<T> {
// ...
}
Gen
是一个泛型类(一种特定类型的泛型类型),因为它被声明为至少有一个类型参数,在本例中为T
。实例化Gen
时,有时在其他情况下,提供绑定到T
的类型表达式:
Gen<?> gen = new Gen<String>();
给定的类型表达式(?
和String
)通常也称为“类型参数”,就像类T
定义中的Gen
一样。 特定类型参数可以由泛型类(例如:List<String>
中的Gen<List<String>>
)组成,但“泛型类”不是“类型参数”的同义词。
ArrayList
也是一样的。它是具有一个类型参数的泛型类。特定声明提供类型表达式作为这些类型参数的值:
List<Integer> list = new ArrayList<Integer>();
在那里,List<E>
和ArrayList<E>
是通用类型;后者特别是一般类。双方的Integer
是适用于list
声明的类型参数和ArrayList
的实例化;在这种情况下,它不被称为“通用类”。
答案 1 :(得分:2)
当我声明时,
www.domain.com
它声明了一个通用类型的整数正确吗?
这是不正确的。您正在声明/创建一个Gen<Integer> iOb = new Gen(88);
对象,该对象包含Gen
。在T extends Object
代码内,您只能使用Gen
上允许使用的功能,例如Object
。
Java编译器记得getClass()
将引用必须持有iOb
对象的Gen
对象,并将在返回值上生成自动类型转换Integer
...
getob()
编译器将其解释为编写以下内容:
int v=iOb.getob();
int v = (Integer) iObj.getob();
被视为仅返回getob()
。请注意,这是一个编译时转换,以方便程序员。
但是,如果我以同样的方式宣布一个arraylist?在arraylist的情况下,它是尖括号中的类型,但是,研究泛型,它说尖括号中的类型是泛型类型?我怎么知道它是一个类类型的arraylist还是泛型???
Object
声明一个泛型类型。尖括号之间的部分是&#34;类型参数&#34;对于通用类。
当泛型类用作变量的类型时,它被认为是泛型类的特化,而类型参数可以是具体类,接口或另一个泛型类。
答案 2 :(得分:2)
你的问题措辞有些奇怪,但我会试一试。泛型用于类型安全,特别是用于集合。如果你要声明一个这样的ArrayList:
ArrayList a= new ArrayList();
然后你可以把你想要的任何类型的对象放到ArrayList中。这是非常危险的,因为当您从列表中检索对象时,您需要知道将从列表中检索哪种对象。你不会想把猫对象拉成人参考!猫不是人!这就是泛型的用武之地。像这样声明你的ArrayList:
ArrayList<People> p= new ArrayList<People>();
允许您具有类型安全性。没有更多问题与那些讨厌的Cat对象进入你的人员阵列!
至于此:
//get the value in Iob notice that no cast is needed
int v = iOb.getob();
你似乎对拆箱感到困惑。它与泛型无关。我建议你查看自动装箱和拆箱。
最后:
//get the value of strOb, again notice that no cast is needed
String str = strOb.getob();
我不明白你在这里不明白。字符串是对象。你放入一个String对象,然后拉出一个String对象。
我还建议创建一个简单的java对象,比如一个人,这样你就可以用你的Gen类创建一个泛型,比如说String,并尝试将Person对象放入。看看它给出了什么错误。
答案 3 :(得分:1)
首先,我们应该澄清一些条款。来自https://docs.oracle.com/javase/tutorial/java/generics/why.html
简而言之,泛型使类型(类和接口)在定义类,接口和方法时成为参数。与方法声明中使用的更熟悉的形式参数非常相似,类型参数提供了一种使用不同输入重用相同代码的方法。不同之处在于形式参数的输入是值,而类型参数的输入是类型。
因此,当您执行Gen<Integer>iOb=new Gen<Integer>(88);
时,Gen
类由类型Gen
组成,但具有泛型类型参数Integer
。 Gen
是一个泛型类,因为类头包含泛型类型参数<T>
。但是,Arraylists也是泛型类,因为它们不限于一种类型,您可以从声明中看出。声明Arraylist时,您可以按照与Gen类相同的方式执行类型声明。例如:Arraylist<String> list = new ArrayList<String>();
Arraylists确实有一个原始类型实现,它在声明中不需要类型参数。例如:Arraylist list = new Arraylist();
但是不建议这样做,如果你以这种方式声明arraylists,Java实际上会给你一个警告,建议你参数化arraylist。
总之,泛型类型是通过类型(https://docs.oracle.com/javase/tutorial/java/generics/types.html)参数化的泛型类或接口。因此,您的Gen
类和内置的Arraylist
Java类都是通用类型。