类型参数的定义

时间:2013-10-09 16:57:28

标签: java generics type-parameter

  1. 我不理解泛型类或方法中类型参数的强大防御。这是一个参考类型,以便......什么?它只是不可再生的类型吗?编译器的所有引用类型是可以重新生成还是不可重新生成,这是真的吗?
  2. 2.考虑众所周知的代码:

    List<? extends String> strs= new ArrayList<String>();
    ? extends String str;//error
    strs.add("sd");//error
    

    为什么? extends String str;无效?我认为如果我们声明对泛型类型的引用,例如某些类型List<E> strs;的{​​{1}},则编译器将类型参数定义为特定类型E

    我不明白案例E中发生了什么? List<? extends String> strsList<? extends String>是否在编译时进行类似解析,或List<String>解析与List<? extends String>不同的某些可复制类型List<E>

2 个答案:

答案 0 :(得分:1)

泛型用于指定类型。

考虑以下类def:

public interface List<E> extends Collection<E>  

这告诉我们,我们有一个可以容纳任何类型元素的List 请注意E没有限制。

如果我们定义一个这样的类:

public class MyList<T extends String> implements List<T>

我们现在有一个实现List的MyList,但只接受String s(或decedents)。

在这个课程中,我们可以参考T

public class MyList<T extends String> implements List<T> {
  private ArrayList<T> internalStorage;

关键点
在类定义中,我们定义了T是什么;它是基于String的任何类 因此可以引用类T内部 然而,在实际实例化类之前,T的味道不会得到修复:

MyList<MyStringType> test = new MyList<MyStringType>(parameters);  //java 6
MyList<MyStringType> test = new MyList<>(parameters);  //java 7, same but shorter.

现在,Java知道T类中的MyList意味着什么是T是MyStringType。
支持知识Java编译类并使用对实际类T的引用替换对MyStringType的所有引用。
它完全忘记了T。

现在在课堂内注意到,提到的T到处都会被MyStringType取代 但是如果我想处理一个字符串,但不一定是MyStringType。

解决方案:
我定义了一个像这样的成员:

List<? extends String> strs;  //Will fill the data in later

现在我们有一个名为strs的List,它只接受字符串,但不会强制使用MyStringType类型的字符串。
此列表不受T实例化时修复的MyList定义的约束 当我们为strs赋值时,如果修复了List的风格。在您的示例中,它将是一个String列表。

? extends String str;//error 

变量无法修复,因为当创建保存变量的类时,无法确定其类型。

答案 1 :(得分:0)

泛型专为读取而非写入而设计。这就是为什么你可以在方法的参数中使用泛型,但是不能用它来声明一个你可以用来读/写的变量: - )