programing

Java Generic 메서드를 정적으로 만드는 방법

goodsources 2022. 7. 10. 21:23
반응형

Java Generic 메서드를 정적으로 만드는 방법

다음은 배열에 단일 항목을 추가하는 Java 범용 클래스를 만드는 방법에 대한 단편입니다.appendToArray를 정적 메서드로 만들려면 어떻게 해야 합니까?메서드 시그니처에 static을 추가하면 컴파일 오류가 발생합니다.

public class ArrayUtils<E> {

        public E[] appendToArray(E[] array, E item) {
            E[] result = (E[])new Object[array.length+1];
            result[array.length] = item;
            return result;
        }
}

당신이 할 수 있는 유일한 일은 서명을

public static <E> E[] appendToArray(E[] array, E item)

중요 사항:

반환값 앞에 있는 범용 표현식에서는 항상 새로운 범용 유형 변수가 도입(선언)됩니다.

또한 유형 간에 변수를 입력합니다(ArrayUtils및 스태틱 방식(appendToArray)는 서로 간섭하지 않습니다.

그럼 이게 무슨 뜻일까요?제 답변으로는<E>은닉하다E부터ArrayUtils<E>방법이 아니라면static.그리고.<E>와는 전혀 관계가 없다E부터ArrayUtils<E>.

이 사실을 더 잘 반영하기 위해 보다 정확한 답은 다음과 같습니다.

public static <I> I[] appendToArray(I[] array, I item)
public static <E> E[] appendToArray(E[] array, E item) { ...

주의:<E>.

스태틱 범용 방식에는 독자적인 범용 선언이 필요합니다(public static <E>)는 클래스의 일반 선언( )과는 별개입니다.public class ArrayUtils<E>).

컴파일러가 정적 범용 메서드를 호출할 때 타입의 모호성에 대해 불만을 제기하는 경우(다시 말씀드리지만, 일반적으로는 만약을 위해), 특정 타입을 사용하여 정적 범용 메서드를 명시적으로 호출하는 방법은 다음과 같습니다._class_.<_generictypeparams_>_methodname_):

String[] newStrings = ArrayUtils.<String>appendToArray(strings, "another string");

이것은 컴파일러가 범용 타입을 판별할 수 없는 경우에만 발생합니다.예를 들어 범용 타입은 메서드 인수와 관련이 없기 때문입니다.

간단하게 설명하겠습니다.

클래스 레벨에서 정의된 제네릭은 (정적) 메서드레벨에서 정의된 제네릭과는 완전히 다릅니다.

class Greet<T> {

    public static <T> void sayHello(T obj) {
        System.out.println("Hello " + obj);
    }
}

위의 코드가 있는 경우 클래스레벨에서 정의되어 있는T는 스태틱메서드에서 정의되어 있는T와는 관계가 없다는 점에 주의해 주십시오.다음 코드도 완전히 유효하며 위의 코드와 동등합니다.

class Greet<T> {

    public static <E> void sayHello(E obj) {
        System.out.println("Hello " + obj);
    }
}

스태틱 메서드는 왜 클래스의 제네릭스와는 별도로 해야 합니까?

이는 클래스를 인스턴스화하지 않고도 정적 메서드를 호출할 수 있기 때문입니다.따라서 클래스가 아직 인스턴스화되지 않았다면 T가 무엇인지 아직 알 수 없습니다.이것이 스태틱 메서드에 독자적인 제네릭이 필요한 이유입니다.

즉, 스태틱 메서드를 호출할 때마다

Greet.sayHello("Bob");
Greet.sayHello(123);

JVM은 다음과 같이 해석합니다.

Greet.<String>sayHello("Bob");
Greet.<Integer>sayHello(123);

둘 다 동일한 출력을 제공합니다.

Hello Bob
Hello 123

범용 클래스가 아닌 범용 메서드가 있음을 나타내려면 type 파라미터를 메서드레벨로 이동해야 합니다.

public class ArrayUtils {
    public static <T> E[] appendToArray(E[] array, E item) {
        E[] result = (E[])new Object[array.length+1];
        result[array.length] = item;
        return result;
    }
}

javadoc에서

일반적인 방법

범용 메서드는 자체 유형 매개 변수를 도입하는 메서드입니다.이는 일반 유형을 선언하는 것과 유사하지만 type 매개 변수의 범위는 선언된 메서드로 제한됩니다.정적 및 비정적 일반 메서드 및 일반 클래스 생성자를 사용할 수 있습니다.

일반 메서드의 구문에는 메서드의 반환 유형 앞에 표시되는 유형 매개 변수 목록(내부 꺽쇠 괄호)이 포함됩니다.정적 일반 메서드의 경우 메서드의 반환 유형 앞에 type parameter 섹션이 표시되어야 합니다.

Util 클래스에는 두 개의 Pair 개체를 비교하는 일반적인 메서드인 compare가 포함됩니다.

public class Util {
    public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
        return p1.getKey().equals(p2.getKey()) &&
               p1.getValue().equals(p2.getValue());
    }
}


public class Pair<K, V> {

private K key;
private V value;

public Pair(K key, V value) {
    this.key = key;
    this.value = value;
}

public void setKey(K key) { this.key = key; }
public void setValue(V value) { this.value = value; }
public K getKey()   { return key; }
public V getValue() { return value; }
}

이 메서드를 호출하기 위한 완전한 구문은 다음과 같습니다.

Pair<Integer, String> p1 = new Pair<>(1, "apple");
Pair<Integer, String> p2 = new Pair<>(2, "pear");
boolean same = Util.<Integer, String>compare(p1, p2);

유형은 굵은 글씨로 표시된 것처럼 명시적으로 제공되었습니다.일반적으로 이것은 생략할 수 있으며 컴파일러는 필요한 유형을 추론합니다.

Pair<Integer, String> p1 = new Pair<>(1, "apple");
Pair<Integer, String> p2 = new Pair<>(2, "pear");
boolean same = Util.compare(p1, p2);

유형 추론이라고 하는 이 기능을 사용하면 각 괄호 사이의 유형을 지정하지 않고 일반 메서드로 일반 메서드를 호출할 수 있습니다.

이 문서를 이해한 후 질문에 대한 답변은 다음과 같습니다.

public static <I> I[] appendToArray(I[] array, I item)

언급URL : https://stackoverflow.com/questions/4409100/how-to-make-a-java-generic-method-static

반응형