java7 새로운 기능 가변 및 비구체적 형식 형식화 파라미터를 사용할 때 경고와 오류 알림 개선

원문
이 페이지에서는 다음 항목을 다룹니다.
  • Heap Pollution
  • 가변 매개 변수 방법과 비구체화 매개 변수
  • 안전 빈틈이 변할 수 있는 비구체화 파라미터의 방법
  • 가변 비구체화 매개 변수에 대한 알림 경고 해제
  • Heap Pollution
    ArrayList와 같이 ArrayList의 매개 변수화 유형은 비구체화 유형이다.하나의 비구체화 유형은 실행할 때 완전히 사용할 수 없다.컴파일링을 할 때 컴파일러는 하나의 유형 지우기 과정을 겪는다. 이 과정에서 파라미터 유형이 파라미터화된 정보를 지우기 때문에 범주가 등장하기 전에 응용 프로그램과 자바 라이브러리가 2진법으로 호환될 수 있도록 한다.
    패라메트릭 변수가 비패라메트릭 객체를 가리킬 때 Heap Pollution이 발생합니다.
            
        List l = new ArrayList<Number>();
        List<String> ls = l;       // unchecked warning
        l.add(0, new Integer(42)); // another unchecked warning
        String s = ls.get(0);      // ClassCastException is thrown

    유형 지우기 프로세스 중 유형 Array List와 List은 각각 Array List와 List가 됩니다.
    이 변수 ls는 매개 변수화List입니다. l 인용이 부여되면 컴파일러가 검사하지 않은 경고를 생성합니까?
     
    컴파일할 때, add 문장에서 컴파일러가 다른 검사하지 않은 경고를 생성합니다. 컴파일러가 변수 l이 Array List 형식을 참조하는지, List 형식을 참조하는지 알 수 없기 때문입니다. 그러나 get 문장에서 컴파일러가 경고나 오류를 일으키지 못했습니다. get 방법을 호출하여 String 대상을 찾으려고 했는데, 결과는 a ClassCastException 를 던졌습니다. 

    List<Number> l List<String> ,Heap Pollution , ? javaSE
     
    또한dd 방법이 호출될 때 and 방법 형식 매개 변수는String이고 실제 매개 변수는Integer이기 때문에 Heap Pollution도 발생했다. 컴파일러가 이 방법을 호출할 수 있는 것은 형식을 지울 때 and 방법의 두 번째 형식 매개 변수가 Object로 바뀌었고 Integer는 Object 서브 형식이기 때문에 컴파일러가 이렇게 할 수 있다. 

    ArrayBuilder.addToList의 예, 이것은 가변적인 매개 변수의 방법으로 주로 T 유형의 대상을 넣는다ListlistArg 
     

    import java.util.*;
    
    public class ArrayBuilder {
    
      public static <T> void addToList (List<T> listArg, T... elements) {
        for (T x : elements) {
          listArg.add(x);
        }
      }
    
      public static void faultyMethod(List<String>... l) {
        Object[] objectArray = l;  // Valid
        objectArray[0] = Arrays.asList(new Integer(42));
        String s = l[0].get(0);    // ClassCastException thrown here
      }
    
    }
    import java.util.*;
    
    public class HeapPollutionExample {
    
      public static void main(String[] args) {
    
        List<String> stringListA = new ArrayList<String>();
        List<String> stringListB = new ArrayList<String>();
    
        ArrayBuilder.addToList(stringListA, "Seven", "Eight", "Nine");
        ArrayBuilder.addToList(stringListA, "Ten", "Eleven", "Twelve");
        List<List<String>> listOfStringLists = new ArrayList<List<String>>();
        ArrayBuilder.addToList(listOfStringLists, stringListA, stringListB);
    
        ArrayBuilder.faultyMethod(Arrays.asList("Hello!"), Arrays.asList("World!"));
      }
    }

    javaSE 7의 컴파일러가 이 방법 ArrayBuilder.addToList 에 대해 다음 경고를 생성합니다
    warning: [varargs] Possible heap pollution from parameterized vararg type T

    컴파일러가 가변적인 방법을 만났을 때 가변적인 형식 매개 변수를 수조로 하고 자바 언어에서는 매개 변수화된 수조의 생성을 허용하지 않으며 이 ArrayBuilder.addToList , T... elements를 형식 매개 변수T[] elements 。 , Object[] elements, ,Heap Pollution 。 , 。로 전환시킨다
    잠재적인 보안 빈틈이 있는 비구체화 형식 매개 변수의 방법
    이 방법은arraybuilder입니다.faultymethod는 왜 컴파일러가 이 몇 가지 방법을 경고하는지 보여 줍니다
    이 방법은 Object 유형 배열objectArgs에 가변적인 비구체적 형식 매개변수를 지정합니다.
    Object[] objectArray = l;
    
    

    이 문구에 Heap Pollution 문제가 잠복되어 있습니다.
    이 문장 컴파일러는 검사하지 않은 경고를 생성하지 않습니다. List<String>... l List[] l이 l은 이것List[] , Object[] , 。이다. , List objectArray , :
     objectArray[0] = Arrays.asList(new Integer(42));

    컴파일러는 경고나 오류를 알리지 않습니다
    만약 네가 아래의 문장으로 Array Builder를 호출한다면.faultyMethod
    ArrayBuilder.faultyMethod(Arrays.asList("Hello!"), Arrays.asList("World!"));
     
     
        ,JVM       a ClassCastException  
    String s = l[0].get(0);    // ClassCastException thrown here

    가변적인 비구체적 형식 매개 변수의 방법으로 경고 제거
    가변적인 매개 변수화 방법을 정의하고 이 방법체가 던져지지 않도록 보장할 수 있다면 ClassCastException ,
  • 다음 메모 추가
  • @SafeVarargs
  • 다음 메모 추가
  • @SuppressWarnings({"unchecked", "varargs"})
  • 컴파일 옵션 사용
  • -Xlint:varargs
    

    예: 아래ArrayBuilder addToList2 andaddToList3
    public class ArrayBuilder {
    
      public static <T> void addToList (List<T> listArg, T... elements) {
        for (T x : elements) {
          listArg.add(x);
        }
      }
    
      @SuppressWarnings({"unchecked", "varargs"})
      public static <T> void addToList2 (List<T> listArg, T... elements) {
        for (T x : elements) {
          listArg.add(x);
        }
      }
    
      @SafeVarargs
      public static <T> void addToList3 (List<T> listArg, T... elements) {
        for (T x : elements) {
          listArg.add(x);
        }
      }
    
      // ...
    
    }public class HeapPollutionExample {
    
      // ...
    
      public static void main(String[] args) {
    
        // ...
    
        ArrayBuilder.addToList(listOfStringLists, stringListA, stringListB);
        ArrayBuilder.addToList2(listOfStringLists, stringListA, stringListB);
        ArrayBuilder.addToList3(listOfStringLists, stringListA, stringListB);
    
        // ...
    
      }
    }

    이 예에서는 컴파일러가 다음 경고를 생성합니다.
  • addToList :

  • 방법 정의: [unchecked] Possible heap pollution from parameterized vararg type T메서드에서 호출: [unchecked] unchecked generic array creation for varargs parameter of type List<String>[]
  • addToList2 :

  • 메서드에서 호출: [unchecked] unchecked generic array creation for varargs parameter of type     :
  • addToList3 :

  • 방법 정의와 호출에 경고가 없습니다
    주의:java SE 5와 6에서 프로그래머는 그가 호출한 방법이 Heap Pollution에서 발생하지 않을 것을 보증한다. 만약에 이 방법이 이 프로그래머가 쓴 것이 아니라면 프로그래머는 보증하기 어렵다. java SE 7에서 이 방법을 쓰면 프로그래머는 Heap Pollution이 발생하지 않을 것을 보증한다.
       

     

     

     



     


     

     

     

     

     

    좋은 웹페이지 즐겨찾기