[java] Java Generic 메소드를 정적으로 만드는 방법은 무엇입니까?

다음은 단일 항목을 배열에 추가하기 위해 Java 일반 클래스를 작성하는 방법에 대한 스 니펫입니다. appendToArray를 정적 메서드로 만들려면 어떻게해야합니까? 메소드 서명에 정적을 추가하면 컴파일 오류가 발생합니다.

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) 사이의 형식 변수는 서로 간섭하지 않습니다.

그래서 이것이 의미하는 바는 : 내 대답 에서 메소드가 아닌 경우 from을 <E>숨길 것 입니다. 그리고 from 과 는 아무런 관련이 없습니다 .EArrayUtils<E>static<E>EArrayUtils<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");

예를 들어 제네릭 형식은 메서드 인수와 관련이 없기 때문에 컴파일러가 제네릭 형식을 확인할 수없는 경우에만 발생합니다.


답변

제네릭 클래스가 아닌 제네릭 메서드가 있음을 나타내려면 형식 매개 변수를 메서드 수준으로 이동해야합니다.

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;
    }
}


답변

간단한 방법으로 설명하겠습니다.

클래스 수준에서 정의 된 제네릭은 (정적) 메서드 수준에서 정의 된 제네릭과 완전히 분리됩니다.

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


답변