I learned java generics some time ago, but now I'm learning collections and found some code that I don't understand. Here is the code:
我以前学过java泛型,但是现在我正在学习集合,并发现了一些我不理解的代码。这是代码:
static <E> List<E> nCopies(int n, E value)
It is from class java.util.Collections
.
它来自类java.util.Collections。
My question is why there is:
我的问题是为什么会有:
<E> List<E>
and not only
不仅
List<E>
Obviously I am missing something, can someone clarify this for me?
很明显我错过了什么,有人能帮我澄清一下吗?
4 个解决方案
#1
11
In <E> List<E>
, the first <E>
denotes that E
is a type parameter. If you hadn't specified it, then Java would think the E
in E value
referred to an actual class named E
, and ask you to import it. See generic methods.
在
#2
13
You use the <E>
to typify the method you are defining.
您使用
The most common example of generics is to have a typified class like this:
泛型最常见的例子是有一个类型化的类:
public class SomeClass<E> {
...
}
Then, when you are creating a new object of that class you define the type directly like this:
然后,当您创建该类的新对象时,您直接定义类型如下:
new SomeClass<String>();
That way any method in that class that refers to , will treat as a String, for that instance.
这样,类中引用的任何方法,都将被视为字符串。
Now consider a static method (which is not bound to any particular instance of a class), in order to typify that method you have use another kind of typification which applies to methods, like this:
现在考虑一个静态方法(它不绑定到类的任何特定实例),为了对该方法进行类型化,您使用了另一种类型的类型化,这种类型化适用于方法,如下所示:
static <E> List<E> nCopies(int n, E value)
You use the <E>
before the return type to say "this particular method will consider some E when it executes". What <E>
will be is decided when you invoke the method:
在返回类型之前使用
nCopies(3, "a");
In this example <E>
will be a String, so the return type will be a List<String>
.
在本例中,
Finally, you can even mix them both:
最后,你甚至可以将两者混合:
public class SomeClass<E> {
public <F> void doSomething(E e, F f){
...
}
}
In this case, if you have an instance of SomeClass, the E in the doSomething method will always be String (for that instance), but the F can be anything you want it to be.
在本例中,如果您有一个SomeClass的实例,doSomething方法中的E将始终是String(对于该实例),但是F可以是您希望的任何值。
#3
3
The <E>
is required to tell the compiler that you intend to use E
as a type parameter, the same way you do when you make a generic class (e.g. public interface List<E>
).
需要
Since there is no rule (only conventions) on interface or class names being more than one character, and no rule (only conventions) that type parameter names have to be one character, the compiler would not know you intended it to be a type parameter rather than a concrete class name.
由于接口或类名上没有规则(只有约定)是多于一个字符,而且类型参数名称必须是一个字符的规则(只有约定),因此编译器不会知道您希望它是一个类型参数,而不是一个具体的类名。
Edit
A lot of people have been saying this is directly related to static methods. That is not true. You can have an instance method that is generic on its own type parameters as well (though typically, the type parameters will be related to the class type parameters).
很多人都说这与静态方法直接相关。这是不正确的。您还可以拥有一个实例方法,该方法在自己的类型参数上也是通用的(尽管通常,类型参数将与类类型参数相关)。
Here's an example of where you could have this:
这里有一个例子可以说明这一点:
public class MyList<E> {
public <N super E> MyList<N> createCopy() {
//...
}
}
This method would allow you to create a copy of the list but not restrain you to using the same type as the list you have, but rather allowing you to use a supertype. For example:
该方法允许您创建列表的副本,但不限制您使用与列表相同的类型,而是允许您使用超类型。例如:
MyList<Integer> integers = createList(1, 2, 5);
MyList<Number> numbers = integers.createCopy();
#4
2
List<E>
is the return type for the method whereas <E>
is the type being passed in (This is inferred by the compiler from what is being passed as E value
).
List
static <E> List<E> someMethod(E myObject)
{
E objectOfMyType = myObject;
List<E> myList = new ArrayList<E>();
...
return myList;
}
This would be called as:
这将称为:
MyObject o = new MyObject();
List<MyObject> myList = SomeClass.someMethod(o);
IMHO the syntax for methods is kinda goofy, but there you have it. The relavent Oracle tutorial is here: http://download.oracle.com/javase/tutorial/extra/generics/methods.html
方法的语法有点傻,但是你已经知道了。relavent Oracle教程在这里:http://download.oracle.com/javase/tutorial/extra/generics/methods.html。
#1
11
In <E> List<E>
, the first <E>
denotes that E
is a type parameter. If you hadn't specified it, then Java would think the E
in E value
referred to an actual class named E
, and ask you to import it. See generic methods.
在
#2
13
You use the <E>
to typify the method you are defining.
您使用
The most common example of generics is to have a typified class like this:
泛型最常见的例子是有一个类型化的类:
public class SomeClass<E> {
...
}
Then, when you are creating a new object of that class you define the type directly like this:
然后,当您创建该类的新对象时,您直接定义类型如下:
new SomeClass<String>();
That way any method in that class that refers to , will treat as a String, for that instance.
这样,类中引用的任何方法,都将被视为字符串。
Now consider a static method (which is not bound to any particular instance of a class), in order to typify that method you have use another kind of typification which applies to methods, like this:
现在考虑一个静态方法(它不绑定到类的任何特定实例),为了对该方法进行类型化,您使用了另一种类型的类型化,这种类型化适用于方法,如下所示:
static <E> List<E> nCopies(int n, E value)
You use the <E>
before the return type to say "this particular method will consider some E when it executes". What <E>
will be is decided when you invoke the method:
在返回类型之前使用
nCopies(3, "a");
In this example <E>
will be a String, so the return type will be a List<String>
.
在本例中,
Finally, you can even mix them both:
最后,你甚至可以将两者混合:
public class SomeClass<E> {
public <F> void doSomething(E e, F f){
...
}
}
In this case, if you have an instance of SomeClass, the E in the doSomething method will always be String (for that instance), but the F can be anything you want it to be.
在本例中,如果您有一个SomeClass的实例,doSomething方法中的E将始终是String(对于该实例),但是F可以是您希望的任何值。
#3
3
The <E>
is required to tell the compiler that you intend to use E
as a type parameter, the same way you do when you make a generic class (e.g. public interface List<E>
).
需要
Since there is no rule (only conventions) on interface or class names being more than one character, and no rule (only conventions) that type parameter names have to be one character, the compiler would not know you intended it to be a type parameter rather than a concrete class name.
由于接口或类名上没有规则(只有约定)是多于一个字符,而且类型参数名称必须是一个字符的规则(只有约定),因此编译器不会知道您希望它是一个类型参数,而不是一个具体的类名。
Edit
A lot of people have been saying this is directly related to static methods. That is not true. You can have an instance method that is generic on its own type parameters as well (though typically, the type parameters will be related to the class type parameters).
很多人都说这与静态方法直接相关。这是不正确的。您还可以拥有一个实例方法,该方法在自己的类型参数上也是通用的(尽管通常,类型参数将与类类型参数相关)。
Here's an example of where you could have this:
这里有一个例子可以说明这一点:
public class MyList<E> {
public <N super E> MyList<N> createCopy() {
//...
}
}
This method would allow you to create a copy of the list but not restrain you to using the same type as the list you have, but rather allowing you to use a supertype. For example:
该方法允许您创建列表的副本,但不限制您使用与列表相同的类型,而是允许您使用超类型。例如:
MyList<Integer> integers = createList(1, 2, 5);
MyList<Number> numbers = integers.createCopy();
#4
2
List<E>
is the return type for the method whereas <E>
is the type being passed in (This is inferred by the compiler from what is being passed as E value
).
List
static <E> List<E> someMethod(E myObject)
{
E objectOfMyType = myObject;
List<E> myList = new ArrayList<E>();
...
return myList;
}
This would be called as:
这将称为:
MyObject o = new MyObject();
List<MyObject> myList = SomeClass.someMethod(o);
IMHO the syntax for methods is kinda goofy, but there you have it. The relavent Oracle tutorial is here: http://download.oracle.com/javase/tutorial/extra/generics/methods.html
方法的语法有点傻,但是你已经知道了。relavent Oracle教程在这里:http://download.oracle.com/javase/tutorial/extra/generics/methods.html。