Home >Java >javaTutorial >How to use Java generic methods

How to use Java generic methods

王林
王林forward
2023-05-01 14:16:062642browse

Generic methods

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 instance cannot be sensed and needs to be changed to
public static void test(T t)

toString() There is no problem, toString is the method of Object.

Generic parameters and type elimination

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.

How to use Java generic methods

#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.

Questions when creating a new generic object

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 and ArrayList

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:

How to use Java generic methods

  • ##Child c = list.get() or Parent The operation done by p = list.get() is to force the internal super Child> to the external Parent or child when returning, which is unreasonable because the compiler thinks that the child's parent class

    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.

Q:

List> list = new ArrayList<a>();</a>
What are the characteristics of this list?

A: Neither get nor add can be used, only operations such as remove with no return value and no input A can be performed.

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.

Q: Will the following code report an error?

   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>
A: No error will be reported. The results will be printed normally.

How to use Java generic methods

PECS principle

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!

Suppose there is a class defined as follows:

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>
Then T is the generic parameter.

Q: Can the following code run normally?

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: It cannot run normally, both pushList and pollList will report errors

Because after checking, the compiler thinks that List and List are not the same thing!

Q: If we want to support pushList above, how should we modify the definition of pushList method?

A: Change it to this:

// 把输入参数塞给自己,类似于生产操作
public void pushList(List extends T> t) {
    list.addAll(t);
}
That is, the compiler thinks that List and List extend Number> are the same thing, allowed!

Q: If you want to support pollList , how to modify the definition?

A:

// 把自己的内容塞给输入参数,类似于让输入参数做消费。
public void pollList(List super T> t) {
    t.addAll(list);
}

因为是把自己的东西塞给输入参数, 而想要能塞进去,必须保证自己这个T,是输入参数的子类,反过来说,输入参数必须是T的父类,所以用super
于是编译器认为,List 和List super Number>是一个东西,允许!

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!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete