2014-09-05 4 views
4

최근에 나는 이상한 것처럼 보이는 코드를 읽었습니다. 우리가 알고있는 것처럼 우리는 컬렉션을 사용할 필요가있을 때 컬렉션에서 generic 타입을 초기화해야합니다. 또한 컬렉션에는 컬렉션을 요소로 포함 할 수 있습니다.ArrayList 일반 유형 없음

코드 : 우리는 컬렉션을 요소의 실제 유형을 준 있지 않기 때문에 우리가 객체를 생성 할 ArrayList result = new ArrayList();를 사용할 수있는 이유

public class Solution { 
public static void main(String args[]) { 
    ArrayList res = returnlist(); 
    System.out.print(res.get(0)); 
} 
public static ArrayList<ArrayList<Integer>> returnlist() { 
    ArrayList result = new ArrayList(); 
    ArrayList<Integer> content = new ArrayList<Integer>(); 
    content.add(1); 
    result.add(content); 
    return result; 
}} 

내 질문이

  • 입니다.
  • result.add(content);을 사용하여 컬렉션에 컬렉션을 추가 할 수있는 이유는 무엇입니까? "결과"는 단순한 컬렉션입니다. 우리는로 정의하지 않은 그것은 제네릭 자바에 함께 오기 전에에서 남은 (자바 4 또는 5 나는 생각한다)를 할 수있다 ArrayList

답변

7

Java 일반 콜렉션은 이전 J2SE 5.0과의 하위 호환성을 보장하기 위해 유형과 함께 저장되지 않습니다. 유형 정보는 일반 콜렉션에 추가 될 때 제거됩니다. 이를 Type Erasure이라고합니다.

즉, 제네릭 컬렉션을 비 제너릭 참조에 할당 할 수 있습니다.

모든 Java 제네릭이 실제로하는 일은 일반 목록에 잘못된 유형을 추가 할 수 없으므로 검색시 캐스팅을 수행하지 않아도됩니다. explicit; 여전히 완료 되더라도 implicitly.에 또한

this answer의 자바 부분은 그냥

  • this article은 또한 당신이 더 완전한 방법으로 요구하고 있었는지 기본적으로 커버 한 말에 좀 더 깊이 간다

  • +1

    +1 이것이 가장 유익한 대답이라고 생각합니다. – ne1410s

    +1

    +1 내정. @ ne1410s – Kai

    +0

    2 +1 +1 점수 만 ... StackOverflow가 계산 능력을 잃었습니까? : P –

    0

    ArrayList의.

    +0

    반드시 잔여는 아니지만 확실히 제네릭을 사용하지 않는 기능입니다. 결과물을 얻을 때 아이템을 사용하려면 아이템을 캐스팅해야합니다. –

    +0

    예. 제네릭없이 ArrayList에 저장 한 내용을 처리해야하는 것처럼 보입니다. – Kai

    0

    제네릭은 Java 5에서만 Java에 추가되었습니다. 그 전에는 컬렉션을 사용할 때 항상 개체 컬렉션을 의미했습니다. 이전 구문과 마찬가지로 이전 버전과의 호환성을 유지합니다. 따라서 ArrayList result = new ArrayList()은 실제로 ArrayList<Object>을 생성합니다. ArrayList도 객체이기 때문에 result 변수에 content을 추가 할 수 있습니다.

    +0

    의미가 있습니다. 그러나 일일 프로그래밍에서 제네릭 없이도 컬렉션을 사용하는 것이 여전히 인기있는 방법입니까? – Kai

    +0

    새 코드에는 권장되지 않습니다. 그러나 Java 5 이전에 작성된 많은 코드가 있으며 코드를 유지하거나 확장 할 때 사람들은 이전 스타일을 사용하는 경향이 있습니다. –

    +0

    대단히 감사합니다. – Kai

    0

    ArrayList result = new ArrayList();을 사용하여 개체를 만들 수있는 이유는 컬렉션에 실제 요소 유형을 지정하지 않았기 때문입니다.

    자바가 역 호환되기를 원하기 때문입니다. Generics는 타입 안전성을 보장하는 컴파일러 기능이 더 많으며, 콜렉션은 런타임에 모든 유형의 객체를 저장할 수 있습니다.

    자바 컴파일러는이 당신에게 컴파일러 오류를 제공하지 않습니다하지만 당신은 형식없이 일반적인 클래스를 사용하는 것이 안전하지 않은 경고 컴파일러를 제공해야합니다.

    2

    그냥 최대 p rovide 요약 대답

    옛날 방식 : "개체"


    새로운 방법을 개최 ArrayList에 생성됩니다

    (A) ArrayList result = new ArrayList(); 
    

    는 :

    ArrayList<Integer> content = new ArrayList<Integer>(); 
    

    이 개최 ArrayList에를 나타냅니다 "정수"개체. 이것은 컴파일 타임 형식 검사 목적을 위해 도입되었습니다.


    이유는 무엇입니까?

    첫 번째 경우를 고려하십시오. 입력 유형은 Object입니다. 우리는 Object가 모든 클래스의 수퍼 클래스라는 것을 알고 있습니다. Integer 객체, String 객체 등을 전달할 수 있습니다. 데이터를 가져올 때 개발자는 적절한 유형 캐스팅을 수행해야합니다. 개발자가 처음

    Integer integer=(Integer) content.get(0); 
    

    이 작동하도록되어있는 데이터를 가져 오는 동안 그는 다음과 같은 배역을 추가하도록 코드가 정수 객체를 받아 들일 것입니다 생각 말해봐. 그러나 실수로 String을 전달하면 런타임 오류가 발생합니다.

    어떻게 피할 수 있습니까? 도입으로

    시간 검사


    작동 원리

    컴파일?

    매개 변수화 된 유형을 지정할 때 Integer 객체 만 ArrayList 컬렉션에 추가 할 수 있습니다. 그렇지 않으면 오류가 표시됩니다.

    content.add(3); // will work 
    content.add("HARSHAD"); // error shown 
    

    파라미터 일반적인 유형 목록에서 검색 할 수있는 방법을 올바른 데이터 유형 검사 목적이 있다면?

    컴파일러는 암시 적으로 형식 변환을 수행합니다.예제 코드 참조

    List<Integer> list=new ArrayList<Integer>(); 
    list.add(1); 
    list.add(2); 
    Integer integer=list.get(0); 
    System.out.println(integer); 
    

    컴파일을 수행 할 때 실제로 컴파일러가 수행하는 작업은 무엇입니까?

    //perform type erasure 
    (B) List list=new ArrayList(); 
        list.add(1); 
        list.add(2); 
    
    // the arraylist inturn accepts Object when you run the code 
    
    //add casting 
    Integer integer=(Integer)list.get(0); 
    

    당신은 코드 (A)와 (B) 모두가 동일한 표시되면 결론. 차이점은 두 번째 경우 컴파일러는 암시 적으로 동일한 작업을 수행한다는 것입니다.

    마지막으로 귀하의 질문에 대답하는

    ...

    ArrayList result = new ArrayList(); 
    

    은 이전 버전과의 호환성을 위해 허용됩니다. 이것은 권장되지는 않지만.

    공식 링크 Oracle docs에서 동일한 개념을 설명합니다.