는 일반적으로 다음과 같이 정의됩니다. 즉,
public class FTest { public <t> List<t> f(T t){...}; }</t></t>
일반 매개변수를 추론하는 세 가지 방법:
1 결정된 일반 유형을 f 바로 앞에 추가합니다. ()
fTest.<integer>f(xxx)</integer>
2 , 입력 매개변수에 의해 결정되는 다음 추론은 Integer
int number = 0; fTest.f(number)
3입니다. 반환 값
List<integer> list = fTest.f(xxx);</integer>
에 의해 결정될 수 있습니다. Q: 다음 코드에 어떤 문제가 있나요? toString()이 있나요?
public class A<t> { public static void test(T t){ System.out.println(t.toString()); } }</t>
A: 테스트는 정적 메서드이므로 A
에서 T를 감지할 수 없으며
public static
toString()으로 변경해야 합니다. 문제 없습니다. toString은 객체 메서드입니다.
Q: 런타임 시 일반 매개변수 T는 어떻게 되나요?
A: 객체로 통합되었으며 어떤 유형 정보도 포함하지 않습니다.
Q: 일반 매개변수 T의 비교에 인스턴스오브를 사용할 수 있나요?
class A<t> { void f(Object arg) if(arg instanceof T) { ... } }</t>
A: 아니요, 컴파일러는 오류를 보고합니다.
Q: 일반 매개변수 T에 대해 새 T() 또는 새 T[] 작업을 수행할 수 있나요?
A: 아니요, 컴파일러는 오류를 보고합니다.
Q: 일반 매개변수 객체에서 메서드를 호출할 수 있나요?
T.f();
A: Object의 메서드만 호출할 수 있습니다.
Q: T를 강제 변환에 사용할 수 있나요?
T t = (T)object;
A: 실행할 수 있지만 변환이 실제로 발생하지 않으며 컴파일 중에 경고 경고가 발생합니다.
먼저 기본 클래스인 Parent와 하위 클래스인 Child가 있다고 가정합니다.
class Parent{} class Child extends Parent{}
다음 질문에 답하세요.
Q: 다음 문장에 문제가 있나요?
List<parent> list = new ArrayList<child>()</child></parent>
A: 문제가 있습니다. 편집이 잘못되었습니다. List
Q:
List extends Parent> list = new ArrayList<child>();</child>
이 목록의 특징은 무엇인가요?
A: 이 목록은 A a = list.get()을 호출할 수 있지만 list.add(new Parent())
이유:
list.get()에서 수행한 작업은 다음과 같습니다. 내부 내부 확장 상위>로 변환하는 것은 합리적이지 않습니다. 왜냐하면 이 Parent 객체가 어떤 Parent 하위 클래스로 변환될 수 있는지 모르기 때문입니다.
List super Child> list = new ArrayList<parent>();</parent>
아래 오류를 보고할 사람
list.add(new Child()) list.add(new Parent()) Parent a= list.get(); Child b = list.get()
의 상위 클래스가 반드시 상위 또는 하위로 변환되지 않을 수 있다고 생각하므로 이러한 동작은 금지됩니다( 부모 클래스와 같은 부모 클래스는 객체이지만 객체가 반드시 부모 또는 자식으로 변환될 필요는 없습니다. *list.add(new Child())에 의해 수행되는 작업은 입력 중에 외부 하위 또는 상위를 내부 super Child>로 변환하는 것입니다. 부모 수업.
List> list = new ArrayList<a>();</a>
PS: 참고로 get 또는 add 메서드를 호출할 수 없다는 의미는 아니지만 get 또는 add를 호출할 때 객체 A를 사용하여 작동할 수 없다는 의미입니다.
즉, add(A) 또는 A a = get(0)은 할 수 없습니다
하지만 add(object) 또는 Object o = get(0)은 가능합니다
왜냐하면? Object로 변환은 가능하지만 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>
PECS 원리와 위의 차이점에 주목하세요!
위에 언급된 "extend" 또는 "supert"는 모두 개체를 선언할 때 사용됩니다.
그리고 일반 객체의 메소드 입력 매개변수에는 PECS 원리가 사용됩니다!
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: 다음과 같이 변경하세요.
// 把输入参数塞给自己,类似于生产操作 public void pushList(List extends T> t) { list.addAll(t); }
아:
// 把自己的内容塞给输入参数,类似于让输入参数做消费。 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元素的父类容器。
위 내용은 Java 일반 메소드를 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!