are generally defined as follows, that is, a
public class FTest { public <t> List<t> f(T t){...}; }</t></t>
is added in front of the method. Three generic parameter inference methods:
1. Directly add the determined generic type
fTest.<integer>f(xxx)</integer>
2 in front of f(), and determine it through the input parameters. The following inference is Integer
int number = 0; fTest.f(number)
3, which can be passed Return value OK
List<integer> list = fTest.f(xxx);</integer>
Q: What is wrong with the following code? Is toString() there?
public class A<t> { public static void test(T t){ System.out.println(t.toString()); } }</t>
A: test is a static method, so the T
in the A
public static
toString() There is no problem, toString is the method of Object.
Q: What will the generic parameter T become at runtime?
A: Unified into Object and does not contain any type information.
Q: Can instanceof be used for comparison of generic parameter T?
class A<t> { void f(Object arg) if(arg instanceof T) { ... } }</t>
A: No, the compiler will report an error.
Q: Can the new T() or new T[] operation be performed on the generic parameter T?
A: No, the compiler will report an error.
#Q: Can I call methods in generic parameter objects?
T.f();
A: Only methods of Object can be called.
Q: Can T be used for forced conversion?
T t = (T)object;
A: It can run, but the transformation will not actually occur, and a warning warning will be triggered during compilation.
Assume that there are two classes, the base class Parent and the subclass Child
class Parent{} class Child extends Parent{}
Answer the following questions:
Q: Below Is there something wrong with this sentence?
List<parent> list = new ArrayList<child>()</child></parent>
A: There is a problem, the compilation is wrong. There is no parent-child relationship between List
Q:
List extends Parent> list = new ArrayList<child>();</child>
What are the characteristics of this list?
A: This list can call A a = list.get(), but cannot list.add(new Parent())
Reason:
list What .get() does is to force-convert the internal extend Parent> to Parent when returning. This is reasonable. Any subclass of Parent can be converted to Parent
list.add(new Parent ()) is to convert the external A into the internal extend Parent> during input. This is unreasonable because we don't know which Parent subclass this Parent object can be converted into.
Q:
List super Child> list = new ArrayList<parent>();</parent>
What are the characteristics of this list?
Who will report an error below
list.add(new Child()) list.add(new Parent()) Parent a= list.get(); Child b = list.get()
A: The screenshot is as follows:
Not necessarily can be converted to parent or child, so this behavior is prohibited (for example, the parent class of parent is object, but object may not be converted to parent or child). The operation done by *list.add(new Child()) is to convert the external child or parent into the internal super Child> during input. This is reasonable, because child and parent can definitely be converted into child 's parent class.
List> list = new ArrayList<a>();</a>
PS: Note that it does not mean that the get or add method cannot be called, but that when calling get or add, the object A cannot be used to operate.
That is, you cannot do add(A) or A a = get(0)
But you can do add(object) or Object o = get(0)
Because? It can be converted to Object, but cannot be converted to A.
List<fruit> fruitList = new ArrayList(); fruitList.add(new Fruit()); List<apple> appleList = new ArrayList(); appleList.add(new Apple()); fruitList.addAll(appleList); System.out.println(fruitList);</apple></fruit>
Pay attention to the difference between the PECS principle and the above!
The ? extend or ? supert mentioned above are both used when declaring objects.
The PECS principle is used for method input parameters of generic objects!
public static class MyList<t> { List<t> list = new ArrayList(); // 把输入参数塞给自己,类似于生产操作 public void pushList(List<t> t) { list.addAll(t); } // 把自己的内容塞给输入参数,类似于让输入参数做消费。 public void pollList(List<t> t) { t.addAll(list); } }</t></t></t></t>
MyList<number> myList = new MyList(); List<integer> intList = new ArrayList(); myList.pushList(intList); List<object> objectList = new ArrayList(); myList.pollList(objectList);</object></integer></number>
A: Change it to this:
// 把输入参数塞给自己,类似于生产操作 public void pushList(List extends T> t) { list.addAll(t); }
A:
// 把自己的内容塞给输入参数,类似于让输入参数做消费。 public void pollList(List super T> t) { t.addAll(list); }
因为是把自己的东西塞给输入参数, 而想要能塞进去,必须保证自己这个T,是输入参数的子类,反过来说,输入参数必须是T的父类,所以用super
于是编译器认为,List
PECS原则出自Effective Java, 注意只是一个编程建议而已!
如果有一个类A,泛型参数为T
如果他一般只用于接收输入容器List后,塞入自己内部的T容器, 则类A就叫生产者, 因此输入参数最好定义为 extend T>最好, 以便能接收任何T子类的容器。
如果他一般只用于接收输入容器后List, 把自己内部的T元素塞给它, 那么这个类A就叫消费者, 输入参数最好定义为 super T>\ 最好, 以便自己的T元素能塞给任何T元素的父类容器。
The above is the detailed content of How to use Java generic methods. For more information, please follow other related articles on the PHP Chinese website!