我想在语言中添加对泛型的支持,但在此之前,我需要更清楚地了解内部的泛型。
我目前的理解是实例化类:
class ArrayList<T>
{
public int add(T object)
{
// ...
}
}
创建一个实例,其中T
上的参数类型add
必须与new ArrayList<T>()
上的T
类型参数相同,其中true === (new ArrayList<Date>() instanceof ArrayList)
是真实类型。
实现这一点似乎很简单,但仅适用于此用例。当它需要支持内省时,它就变成了一个更复杂的概念。例如,我不会说:
true === (new ArrayList<Date>() instanceof ArrayList<Date>)
但我会说:
ArrayList<Date>
我的问题是,当使用ArrayList<T>
作为类型引用时,它是一个派生自$list = new ArrayList<Date>();
的类型,还是它本身就是一个类,例如:
class ArrayList
{
public int add(Date $object)
{
// ...
}
}
一个实例:
ArrayList<T>
或者它是T
Date
private void addAttachments( Redemption.RDOMail sourceMail , ref Redemption.RDOMail targetMail )
{
foreach (Redemption.RDOAttachment attachment in sourceMail.Attachments)
{
// Saving attachment files from source mail on local disk
attachment.SaveAsFile(/*File Path*/);
// adding attachment to target mail from saved location
//At this point, target mail has the attachment count incremented
targetMail.Attachments.Add(/*File PAth*/ + attachment.DisplayName);
// deleting file, saved on local disk
File.Delete(/*File Path + attachment.DisplayName*/);
}
targetMail.Save();
// when the mail item is being displayed, the added attachment with the *.EXE,
//or all the other attachment extentions which are blocked from viewing by outlook is gone.
// This does not happen for other attachment files
targetMail.Display();
}
的实例吗?
答案 0 :(得分:1)
Java泛型和C ++模板乍一看看起来很相似,但是以相反的方式实现。正如Steffen Kreutz在评论中所说,java使用类型擦除作为其泛型。类型擦除意味着在编译时,java控制对泛型类的访问,但在运行时,所有类型信息都消失了,ArrayList<Date>
和ArrayList<Integer>
共享完全相同代码。
这与模板完全不同。在模板中,每个具体类都是在编译时实现的,因此(在C ++中)vector<double>
和vector<char>
是两个不同的类,它们的编译代码将是不同的,因为一个将采用双参数,而另一个将采用字符,它们不会在堆栈中以相同的方式传递。
如果你需要一个泛型类来知道它可以接受的类型,你必须明确地使用一个属性来保存它。例如:
class MyGen<T> {
class<T> myClazz;
MyGen(class<T> clazz) {
myClass = clazz;
}
...
}
然后你可以在myClazz上使用反射,因为它是一个在运行时可用的真正的类对象,而T只能在编译时使用,不能通过反射使用。
答案 1 :(得分:0)
泛型只是编译时的助手。如果我们没有泛型,我们会编写这样的代码:
ArrayList list = new ArrayList();
list.add(new Date());
Date date = (Date) list.get(0);
已经引入了泛型来删除必要的强制转换,我们现在可以写:
ArrayList<Date> list = new ArrayList<>();
list.add(new Date());
Date date = list.get(0);
您可能认为ArrayList
类在内部管理Date
数组,但事实上
它管理一个Object
的数组。编译器会在您访问元素的位置插入缺少的强制转换。
使用泛型具有另一个好处。编译器可以检测您是否进行了无效的转换。因此不可能写出这样的东西:
ArrayList<Date> list = new ArrayList<>();
list.add(new Date());
String date = list.get(0);
您可以验证具有不同类型参数的ArrayList
是否仍然使用new ArrayList<String>().getClass().equals(new ArrayList<Date>().getClass())
编译到同一个类。