>Java >java지도 시간 >Java 일반 메소드를 사용하는 방법

Java 일반 메소드를 사용하는 방법

王林
王林앞으로
2023-05-01 14:16:062642검색

일반 메소드

는 일반적으로 다음과 같이 정의됩니다. 즉,

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 void test(T t)

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: 아니요, 컴파일러는 오류를 보고합니다.

Java 일반 메소드를 사용하는 방법

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 ArrayList에는 부모-자식 관계가 없습니다.

Q:

List extends Parent> list = new ArrayList<child>();</child>

이 목록의 특징은 무엇인가요?

A: 이 목록은 A a = list.get()을 호출할 수 있지만 list.add(new Parent())

  • 이유:
    list.get()에서 수행한 작업은 다음과 같습니다. 내부 내부 확장 상위>로 변환하는 것은 합리적이지 않습니다. 왜냐하면 이 Parent 객체가 어떤 Parent 하위 클래스로 변환될 수 있는지 모르기 때문입니다.

Q:

List super Child> list = new ArrayList<parent>();</parent>
이 목록의 특징은 무엇인가요?

아래 오류를 보고할 사람

list.add(new Child())
list.add(new Parent())
Parent a= list.get();
Child b = list.get()
A: 스크린샷은 다음과 같습니다:

Java 일반 메소드를 사용하는 방법

  • Child c = list.get() 또는 Parent p = list.get()은 내부 <를 변경하는 작업을 수행합니다. ;? super Child> 외부 상위 또는 하위로 강제 변환하는 것은 불합리합니다. 왜냐하면 컴파일러는 하위

    의 상위 클래스가 반드시 상위 또는 하위로 변환되지 않을 수 있다고 생각하므로 이러한 동작은 금지됩니다( 부모 클래스와 같은 부모 클래스는 객체이지만 객체가 반드시 부모 또는 자식으로 변환될 필요는 없습니다. *list.add(new Child())에 의해 수행되는 작업은 입력 중에 외부 하위 또는 상위를 내부 super Child>로 변환하는 것입니다. 부모 수업.

Q:

List> list = new ArrayList<a>();</a>
이 목록의 특징은 무엇인가요?

A: get이나 add를 모두 사용할 수 없으며 반환 값이 없고 입력 A가 없는 제거와 같은 작업만 수행할 수 있습니다.

PS: 참고로 get 또는 add 메서드를 호출할 수 없다는 의미는 아니지만 get 또는 add를 호출할 때 객체 A를 사용하여 작동할 수 없다는 의미입니다.
즉, add(A) 또는 A a = get(0)은 할 수 없습니다
하지만 add(object) 또는 Object o = get(0)은 가능합니다
왜냐하면? Object로 변환은 가능하지만 A로 변환은 불가능합니다.

Q: 다음 코드는 오류를 보고합니까?

   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: 오류는 보고되지 않습니다. 결과는 정상적으로 인쇄됩니다.

Java 일반 메소드를 사용하는 방법

PECS 원리

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>
그러면 T는 일반 매개변수입니다.

Q: 다음 코드는 정상적으로 실행될 수 있나요?

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: 정상적으로 실행될 수 없습니다. pushList와 pollList 모두 오류를 보고합니다.

검사 후 컴파일러는 List

Q: 위의 pushList를 지원하려면 pushList 메소드 정의를 어떻게 수정해야 하나요?

A: 다음과 같이 변경하세요.

// 把输入参数塞给自己,类似于生产操作
public void pushList(List extends T> t) {
    list.addAll(t);
}
즉, 컴파일러는 List와 List가 동일하다고 생각합니다.

Q: pollList를 지원하려면 어떻게 해야 하나요? 정의를 수정하려면?

아:

// 把自己的内容塞给输入参数,类似于让输入参数做消费。
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元素的父类容器。

위 내용은 Java 일반 메소드를 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제