2009-04-19 3 views
5
private ArrayList<String> colors = new ArrayList<String>(); 

위의 예를 보면 제네릭의 핵심은 컬렉션에 유형을 적용하는 것입니다. 그래서, 프로그래머의 재량에 따라 String으로 형변환 될 필요가있는 "Objects"배열을 가지는 대신 ArrayList의 컬렉션에 "String"유형을 적용합니다. 이것은 나에게 새로운 것이지만 나는 그것을 정확하게 이해하고 있는지 확인하고 싶다. 이 해석이 맞습니까?Java generics는 주로 컬렉션의 요소에 정적 유형을 강제하는 방식입니까?

답변

1

네, 그게 기본적입니다. generics 이전에는 객체의 ArrayList를 만들어야했습니다. 즉, Object 유형을 목록에 추가 할 수 있습니다. ArrayList에 문자열 만 포함하려는 경우에도 마찬가지입니다.

모든 제네릭은 유형 안전입니다. 즉, 이제 JVM은 목록의 객체가 모두 String인지 확인하고 목록에 비 String 객체를 추가하지 못하도록합니다. 더 좋게도 :이 검사는 컴파일 할 때 수행됩니다.

+3

컴파일시에만 런타임에 실제로 유형 안전을 추가하지 않는다는 점에 유의하십시오. 유형은 런타임에 삭제되고 아무 것도 발생할 수 없습니다. Generics는 문서/명확성 및 컴파일 타임 검사 용입니다. – davetron5000

+1

@ davetron5000 true! Java는이 "기능"유형 삭제를 호출합니다. http://java.sun.com/docs/books/books/tutorial/java/generics/erasure.html 개인적으로, 나는 그것이 가장 성가신 것으로 생각합니다. – poundifdef

+2

기존 코드와의 호환성을 손상시키지 않으면 서 제네릭을 추가 할 수 없었습니다. Neal Gafter는 다음과 같이 여기에 대해 설명합니다. http://gafter.blogspot.com/2006/11/reified-generics-for-java.html –

2

예, 이해가 정확합니다. 콜렉션은 지정된 유형에 상관없이 강력한 유형이므로 많은 런타임 캐스팅을 포함하여 다양한 장점이 있습니다.

+0

런타임 캐스팅이 여전히 발생하지 않습니다 (프로그래머에게 숨김)? – jpalecek

+0

jpalecek : 아니요, rascher를 인용하십시오. "더 좋게 -이 검사는 컴파일 할 때 수행됩니다." –

+0

아직 런타임 캐스팅이 있지만 일반 클래스의 사용자는 대개 직접하지 않아도됩니다. –

1

예. 유형 안전성을 유지하고 런타임 캐스트를 제거하려면 정답입니다.

0

Java site의 자습서를 확인하십시오. 그것은 소개에서 좋은 설명을 제공합니다. 제네릭없이

:

List myIntList = new LinkedList(); // 1 
myIntList.add(new Integer(0)); // 2 
Integer x = (Integer) myIntList.iterator().next(); // 3 

제네릭

List<Integer> myIntList = new LinkedList<Integer>(); // 1' 
myIntList.add(new Integer(0)); // 2' 
Integer x = myIntList.iterator().next(); // 3' 

와 나는 안전한 형태로 생각하고 또한 주조를 저장. autoboxing에 대해 자세히 알아보십시오.

+1

자동 저장 기능을 사용하면 다음을 대체 할 수 있습니다 myIntList.add (new Integer (0)); 그냥 myIntList.add (0); 이며 형식이 지정되지 않은 목록에는 해당되지 않습니다. –

8

를 볼 수 있지만, 그것은 확실히 가장 눈에 띄는 하나입니다.

제네릭은 컬렉션뿐만 아니라 정적 유형 안전성을 보장하기 위해 여러 곳에서 사용할 수 있습니다.

제네릭이 유용 할 수있는 곳을 건너 오게 될 것이기 때문에 언급하고 싶습니다. 그러나 generics/collections 협회에 머물러 있다면 그 사실을 간과 할 수 있습니다.

+5

이 답변을 두 번째로 원합니다. 대부분의 개발자는 먼저 컬렉션 ​​클래스에서 Java 제네릭을 접하게됩니다. 이것은 generics가 컴파일 타임 타입 검사에 큰 개선점을 제공하는 곳입니다. 하지만 일단 제네릭에서 생각하면 많은 패턴이 나타납니다. 예 : public와 같은 팩토리 메서드 T createInstance (Class klass)와 유사합니다. 일반적으로 이제는 캐스트를 할 때 대부분의 시간 동안 제네릭을 사용하여이 형 변환을 타입 안전 식으로 바꿀 수 있습니다. – ordnungswidrig

0

네, 맞습니다. Generics는 프로그램에 컴파일 타임 유형 안전성을 추가합니다. 이는 컴파일러가 잘못된 유형의 객체 (예 : ArrayList)를 넣었는지 여부를 감지 할 수 있음을 의미합니다.

가시적 인 런타임 캐스팅을 제거하고 소스 코드를 제거했지만 JVM은 여전히 ​​백그라운드에서 캐스팅을 수행한다는 점을 지적하고자합니다.

제네릭이 Java에서 구현되는 방식은 캐스트를 숨기고 비 제너릭 바이트 코드를 생성합니다. ArrayList<String>은 여전히 ​​바이트 코드에있는 객체의 ArrayList입니다. 이것에 대한 좋은 점은 바이트 코드가 이전 버전과 호환되도록 유지한다는 것입니다. 나쁜 점은 엄청난 최적화 기회를 놓친다는 것입니다.

0

유형 매개 변수이 필요한 곳에는 범용을 사용할 수 있습니다. 즉, 특정 코드에서 동일해야하지만 유형은 더 많거나 적습니다.

예를 들어, 나의 장난감 프로젝트 중 하나는 Java에서 일반적인 방법으로 컴퓨터 대수를위한 알고리즘을 작성하는 것입니다. 이것은 수학적 알고리즘을 위해 흥미롭지 만 스트레스 테스트를 통해 Java generics를 넣는 것도 중요합니다.

이 프로젝트에서 저는 반지와 필드 및 각각의 요소와 같은 대수 구조에 대한 다양한 인터페이스와 구체적인 클래스를 제공합니다. 반지름은 유형 매개 변수 인 반지름에 대한 정수 또는 다항식의 경우. 작동하지만 장소에서 다소 지루해집니다. 지금까지의 레코드는 다항식의 환원 불가능 성을 테스트하는 알고리즘에서 80 자의 두 개의 완전한 라인에 걸쳐있는 변수 앞에있는 유형입니다. 주요 원인은 복잡한 유형의 고유 한 이름을 부여 할 수 없다는 것입니다.

관련 문제