programing

"A generic array of T is created for a vararargs parameter" 컴파일러 경고를 해결할 수 있습니까?

kingscode 2022. 8. 25. 22:13
반응형

"A generic array of T is created for a vararargs parameter" 컴파일러 경고를 해결할 수 있습니까?

이것은 문제의 코드를 간략화한 버전입니다.어떤 범용 클래스는 범용 타입 파라미터가 있는 다른 클래스를 사용하며 범용 타입 중 하나를 vararargs 파라미터가 있는 메서드에 전달해야 합니다.

class Assembler<X, Y> {
    void assemble(X container, Y... args) { ... }
}

class Component<T> {
    void useAssembler(T something) {

        Assembler<String, T> assembler = new Assembler<String, T>();

        //generates warning:
        // Type safety : A generic array of T is
        // created for a varargs parameter
        assembler.assemble("hello", something);
    }

}

이 경고를 받지 않고 범용 파라미터를 varargs 메서드에 전달할 수 있는 올바른 방법이 있습니까?

물론 뭐랄까...

assembler.assemble("hello", new T[] { something });

범용 배열을 생성할 수 없기 때문에 작동하지 않습니다.

6에서는 6을 추가하는 것 @SuppressWarnings("unchecked")하지 않습니다

이 버그 리포트에는 더 많은 정보가 포함되어 있습니다만, 그 이유는 컴파일러가 범용 타입의 배열을 좋아하지 않기 때문입니다.

Java 7에서는 메서드 선언에 @SafeVarargs 주석을 붙입니다.

fluent 타입의 인터페이스를 원하신다면 빌더 패턴을 사용해 보세요.varargs만큼 간결하지는 않지만 type safe입니다.

정적 범용형 방식은 빌더를 사용할 때 보일러 플레이트의 일부를 제거하는 동시에 타입의 안전성을 유지할 수 있습니다.

건축업자

public class ArgBuilder<T> implements Iterable<T> {

    private final List<T> args = new ArrayList<T>();

    public ArgBuilder<T> and(T arg) {
        args.add(arg);
        return this;
    }

    @Override
    public Iterator<T> iterator() {
        return args.iterator();
    }

    public static <T> ArgBuilder<T> with(T firstArgument) {
        return new ArgBuilder<T>().and(firstArgument);
    }
}

사용법

import static com.example.ArgBuilder.*;

public class VarargsTest {

    public static void main(String[] args) {
        doSomething(new ArgBuilder<String>().and("foo").and("bar").and("baz"));
        // or
        doSomething(with("foo").and("bar").and("baz"));
    }

    static void doSomething(Iterable<String> args) {
        for (String arg : args) {
            System.out.println(arg);
        }
    }
}

vararg 메서드 호출에서 오브젝트에 파라미터를 명시적으로 캐스팅하면 컴파일러는 @SuppressWarnings에 의존하지 않고 만족할 수 있습니다.

public static <T> List<T> list( final T... items )
{
    return Arrays.asList( items );
}

// This will produce a warning.
list( "1", 2, new BigDecimal( "3.5" ) )

// This will not produce a warning.
list( (Object) "1", (Object) 2, (Object) new BigDecimal( "3.5" ) )

// This will not produce a warning either. Casting just the first parameter to 
// Object appears to be sufficient.
list( (Object) "1", 2, new BigDecimal( "3.5" ) )

여기서의 문제는 컴파일러가 구체적으로 어떤 종류의 어레이를 작성해야 하는지 알아내야 한다는 것입니다.메서드가 일반적이지 않은 경우 컴파일러는 메서드의 유형 정보를 사용할 수 있습니다.메서드가 일반인 경우 호출 시 사용된 매개 변수를 기준으로 배열 유형을 파악하려고 합니다.파라미터 타입이 균일한 경우 그 작업은 간단합니다.다른 경우에는 컴파일러가 너무 영리하다고 생각하여 유니언 타입의 범용 어레이를 만듭니다.그럼 어쩔 수 없이 경고를 해야 할 것 같네요.더 간단한 해결책은 유형을 더 잘 좁힐 수 없는 경우 개체 []를 작성하는 것입니다.상기의 솔루션은, 그것을 강요하고 있습니다.

이것을 보다 잘 이해하려면 , 다음의 list2 메서드에 비해, 상기의 리스트 메서드에의 호출을 사용해 주세요.

public static List<Object> list2( final Object... items )
{
    return Arrays.asList( items );
}

해결할 수 있습니다: 을 사용합니다.List<T>!

참조 유형의 배열은 피해야 합니다.

Java의 현재 버전(1.7)에서는 발신자로부터 경고를 삭제하는 방법을 표시할 수 있습니다.다만, 이 점에 주의해 주세요.레거시 어레이가 없는 것이 좋습니다.

List.of()(수정 불가)를 비교적 간결하게 기술하는 방법을 제공합니다.ListJava가 적절한 리터럴 표현을 얻을 때까지.

"Varargs 메서드에서 복구 불가능한 형식 매개 변수를 사용할 때 향상된 컴파일러 경고오류" 기술 노트를 참조하십시오.

Java 7 이후 메서드에 @SafeVarargs를 추가할 수 있으며 클라이언트 코드에 주석을 달 필요가 없습니다.

class Assembler<X, Y> {

    @SafeVarargs
    final void assemble(X container, Y... args) {
        //has to be final...
    }
}

메서드에 과부하가 걸릴 수 있습니다.이 방법은 문제를 해결하지는 않지만 경고 수를 최소화합니다(예, 해킹입니다).

class Assembler<X, Y> {
  void assemble(X container, Y a1) { ... }
  void assemble(X container, Y a1, Y a2) { ... }
  void assemble(X container, Y a1, Y a2, Y a3) { ... }
  void assemble(X container, Y a1, Y a2, Y a3, Y a4) { ... }
  void assemble(X container, Y... args) { ... }
}

범용 타입의 배열로 작업하는 경우, 범용 타입에 대한 참조를 전달하지 않을 수 없습니다.이를 통해 java.lang.reflect를 사용하여 범용 코드를 만들 수 있습니다.어레이

http://java.sun.com/javase/6/docs/api/java/lang/reflect/Array.html

언급URL : https://stackoverflow.com/questions/1445233/is-it-possible-to-solve-the-a-generic-array-of-t-is-created-for-a-varargs-param

반응형