<E>

2013-04-11 48 views
-1

的定义我对于<E>的含义非常困惑。我很困惑什么将被用来代替E.我被告知类型可以放在那里,例如Integer或Double。但我也被告知ArrayList或LinkedList可以放在那里。如果有人可以澄清,将不胜感激。<E>

+0

这只是一个占位符来表示**任何类型**。 – asgs 2013-04-11 02:35:43

+0

@asgs:我会说它表示任何特定的类型。为了避免与'?'产生混淆,它表示任何未指定的类型。首先你可以做出假设,但你不能对后者作出假设。 – Jack 2013-04-11 02:41:16

+0

@Jack,完全同意。 – asgs 2013-04-11 02:42:42

回答

3

Etype variable。这是一个特定类型的变量和占位符。

这种语法与parametric polymorphism一起使用,当您要告诉某个特定的类是通过未指定的类型进行参数化的。

这意味着您可以编写代码,它依赖于E是一个特定类型的规范,并且您可以添加一些约束条件给出的规范,例如<E extends MySuperType>。并且您可以使用E在整个类定义中引用泛型类型。

您已被告知正确的:因为变量无非是一个占位符,它越能包含具体类型如Double,但即使是ArrayList<Double>或最终也是ArrayList<?>,这是不确定的类型的集合。 ?Java generics中的另一个特殊keyword

+0

谢谢,这是完美的。 – user2268305 2013-04-11 03:13:59

2

<E>是一个类型参数,在Java Generics中使用,指定稍后有用的某种类型。例如,在一个容器类中,当你第一次写它时,你不知道它会写什么,但是你的实现关心的是它的内容。

通常情况下,你会看到这样的事情:

List somelist = new ArrayList<Integer>(); //or some other type 

这意味着ArrayList将举行Integers。当然,不管你输入什么类型来代替Integer,实现都保持不变,但Java需要你声明所有引用对象的类型。 (或者你可以偷懒,只说这是一个Object,但打破了类型系统的实用性。)

在其他时候,你可能会看到

class Queue<T> { 
    private LinkedList<T> items = new LinkedList<T>(); 
    public void enqueue(T item) { 
     items.addLast(item); 
    } 
    public T dequeue() { 
     return items.removeFirst(); 
    } 
    public boolean isEmpty() { 
     return (items.size() == 0); 
    } 
} 

(从Javanotes拍摄)。类定义中的变量T捕获传入的类型,并且可以使用T来代替传入的任何类型。例如,方法dequeue返回某个对象,但是具体返回类型为T,该类型仅在类之后才知道写入。在方法enqueue中,您希望将一些对象添加到您的队列中,但特别是类型T,在您实例化类的实例之前,您不知道该对象。

+0

谢谢你的帮助。 – user2268305 2013-04-11 03:14:29

0

< E>是将被传入的“类型”的占位符。这是列表将保存的类型。例如arrayList上的实现。当你想创建一个新的数组列表时,你需要传入列表将要保存的对象类型。

ArrayList示例= new ArrayList();

如果我们分别来看看ArrayList类会是这样的

公共类的ArrayList < E> {...}

基本上是说,我们将举行的一些列表“类型“,但该类型必须在编译时传入,直到此时才会知道。

+0

你可能想重写你的答案。目前还不是很清楚,即“该列表的类型” - 您的意思是“该列表将包含的对象的类型”...... – 2013-04-11 02:57:36

0

<E>泛型只是泛型类型的占位符。

这是必要的,因为你需要某种形式的方法或类,你是为了利用类型的返回类型等

你会很多的例子,如果你只是需要写一个参考看看收集API。

通常如果你只有E你可以传递任何类型作为参数。

+0

是的。哎呀...感谢您指出... – Thihara 2013-04-11 03:06:50

0

<E>是一个类型参数。就像变量可以保存值一样,类型参数保存类型。例如,如果你想创建一个包含任何类型与类型安全两个值的一类,你会怎么做:

class Pair<T1, T2> { 
    private final T1 first; 
    private final T2 second; 

    public Pair(final T1 first, final T2 second) { 
     this.first = first; 
     this.second = second; 
    } 

    public T1 first() {return first;} 

    public T2 second() {return second;} 

    public static <A, B> Pair<A, B> of(final A first, final B second) { 
     return new Pair<A, B>(first, second); 
    } 
} 

这里,我们使用类型参数在两个地方:一个是类在字段类型上进行抽象,并且为静态工厂方法of抽象以对它创建的对的类型进行抽象。我们可以使用这个类像:

public static void main(final String[] args) { 
    final Pair<Integer, String> intStringPair = Pair.of(1, "One"); 
    final int intStringPairFirst = intStringPair.first(); 
    final String intStringPairSecond = intStringPair.second(); 

    final Pair<List<String>, Boolean> listBoolPair = Pair.of(
      Arrays.asList("foo", "bar"), true); 
    final List<String> listBoolPairFirst = listBoolPair.first(); 
    final boolean listBoolPairSecond = listBoolPair.second(); 
} 

在这里你可以看到的类型intStringPairFirstintStringPairSecondlistBoolPairFirstlistBoolPairSecond正确推断不涉及任何转换。

这是为了让你开始。有更多的东西,如差异,边界使用extendssuper和通配符(?),我建议你阅读关于泛型的教程。