source

raw 타입은 무엇이며, 왜 사용하면 안 되는 것입니까?

goodcode 2022. 8. 1. 22:44
반응형

raw 타입은 무엇이며, 왜 사용하면 안 되는 것입니까?

질문:

  • Java에서 raw type은 무엇이며, 왜 새로운 코드에 사용하지 말라는 말을 자주 듣습니까?
  • 생활자를 사용할 수 없다면 대체 방법은 무엇이며, 어떻게 하면 좋을까요?

생타입이 뭐예요?

Java Language Specification에서는 다음과 같이 raw 타입을 정의하고 있습니다.

JLS 4.8 미가공 타입

원시 유형은 다음 중 하나로 정의됩니다.

  • 수반되는 타입 인수 리스트가 없는 범용 타입 선언의 이름을 사용하여 형성되는 참조 타입.

  • 요소 유형이 원시 유형인 배열 유형입니다.

  • 비A-Non-to-(비A-to-)static 타입의 raw 타입의 R에서 것R.

다음은 예를 제시하겠습니다.

public class MyType<E> {
    class Inner { }
    static class Nested { }
    
    public static void main(String[] args) {
        MyType mt;          // warning: MyType is a raw type
        MyType.Inner inn;   // warning: MyType.Inner is a raw type

        MyType.Nested nest; // no warning: not parameterized type
        MyType<Object> mt1; // no warning: type parameter given
        MyType<?> mt2;      // no warning: type parameter given (wildcard OK!)
    }
}

서서,,MyType<E>파라미터 타입(JLS 4.5)입니다.일반적으로 이 유형을 단순이라고 합니다.MyType 말하면, 그 은 「」입니다.MyType<E>.

mt의 첫 번째 글머리 타입 경고를합니다)이 .「 」는 「 」입니다.inn세 번째 글머리 기호에도 원시 유형이 있습니다.

MyType.Nested된 타입의 타입은 .MyType<E>★★★★★★★★★★★★★★★★★★★★.static.

mt1 , , , , 입니다.mt2둘 다 실제 유형 매개 변수를 사용하여 선언되므로 원시 유형이 아닙니다.


생타입이 뭐가 그렇게 특별해요?

기본적으로 raw 타입은 제네릭스가 도입되기 전과 동일하게 작동합니다.즉, 컴파일 시 다음 사항은 완전히 합법적입니다.

List names = new ArrayList(); // warning: raw type!
names.add("John");
names.add("Mary");
names.add(Boolean.FALSE); // not a compilation error!

위의 코드는 정상적으로 동작하지만, 다음과 같은 것도 있다고 가정합니다.

for (Object o : names) {
    String name = (String) o;
    System.out.println(name);
} // throws ClassCastException!
  //    java.lang.Boolean cannot be cast to java.lang.String

에 빠집니다. 왜냐하면names 아닌 것이 들어 있다instanceof String.

당신이 namesStringraw 타입을 사용하여 수동으로 체크할 수 있습니다. add직접 만든 다음 수동으로 캐스팅해서String★★★★★★★★★★★★★★★★의 모든 아이템names더 좋은 것은 raw type을 사용하지 않고 컴파일러가 Java 제네릭스의 파워를 활용하여 모든 작업을 대신하도록 하는 것입니다.

List<String> names = new ArrayList<String>();
names.add("John");
names.add("Mary");
names.add(Boolean.FALSE); // compilation error!

물론 당신이 원한다면namesBoolean 이렇게 List<Object> names위의 코드가 컴파일 됩니다.

「 」를 참조해 주세요.


<Object>형형매 개개?

다음은 Effective Java 2nd Edition, Item 23: 코드에서 원시 유형을 사용하지 마십시오.

raw 타입의 차이점은 무엇입니까?List된 타입 「」는, 「」입니다.List<Object>대략적으로 말하면, 전자는 범용 타입 체크를 제외하고, 후자는 컴파일러에 어떠한 타입의 오브젝트도 보유할 수 있다고 명시하고 있습니다.「 」는 할 수 만,List<String>타입의 List 이 수 없습니다.List<Object> 규칙이 있습니다.List<String>의 raw 의 아형입니다.List, 된 타입은 List<Object> 결과, 와 같은 raw 타입을 사용하면 타입의 안전성이 떨어집니다만, 와 같이 파라미터화된 타입을 사용하면 안전성이 떨어집니다.

하기 위해서, .List<Object> and및을 and andendsendsends를 붙입니다.new Object().

void appendNewObject(List<Object> list) {
   list.add(new Object());
}

Java ★★★★★★★★★★★★★★★★★★★★★★★★★★★. a.List<String> 아니다List<Object>컴파일러 경고는 다음과 같이 생성됩니다.

List<String> names = new ArrayList<String>();
appendNewObject(names); // compilation error!

선언을 하셨다면appendNewObjectList파라미터로서 컴파일되므로 제네릭스에서 얻을 수 있는 타입의 안전성이 상실됩니다.

「 」를 참조해 주세요.


<?>식식매 개개?

List<Object>,List<String>이 , 「」, 「」List<?> 그냥 '그냥List요. '아'와 '아'는 '아'와 '아'는 '아'와 '아'는 '아'와 '아'는 '아'와 '아'의 차이입니다.List<E>" "만 "add(E)List<?> 타입은 raw 이므로 raw 타입은 raw입니다.List안전성이 에, 「형식 안전성이 없다」라고 할 수 있습니다.addList.

이전 스니펫의 다음 변형에 대해 고려해 주십시오.

static void appendNewObject(List<?> list) {
    list.add(new Object()); // compilation error!
}
//...

List<String> names = new ArrayList<String>();
appendNewObject(names); // this part is fine!

는, 「」을할 가능성이 으로부터, 했습니다.List<?> 타입으로 raw 타입으로 선언했을 경우List list컴파일 인 '불변형'을 List<String> names.


원시 유형은 해당 유형의 삭제입니다.

JLS 4.8로 돌아가기:

파라미터화된 유형의 삭제 또는 요소 유형이 파라미터화된 유형의 배열 유형의 삭제를 유형으로 사용할 수 있습니다.이런 타입을 raw 타입이라고 합니다.

[...]

raw 타입의 슈퍼 클래스(각각 슈퍼 인터페이스)는 범용 타입의 파라미터화 중 하나의 슈퍼 클래스(슈퍼 인터페이스)의 소거입니다.

방식 , 즉 비컨스턴스 입니다.static C되지 않은 으로, raw에 .C.

경우, 및 , non-instance-type, non-instance-type, non-instance-type, non-instance-type, non-instance-type.static필드도 지워집니다.

다음 예를 들어 보겠습니다.

class MyType<E> {
    List<String> getNames() {
        return Arrays.asList("John", "Mary");
    }

    public static void main(String[] args) {
        MyType rawType = new MyType();
        // unchecked warning!
        // required: List<String> found: List
        List<String> names = rawType.getNames();
        // compilation error!
        // incompatible types: Object cannot be converted to String
        for (String str : rawType.getNames())
            System.out.print(str);
    }
}

하는 MyType,getNames.List!

JLS 4.6에서는 다음 사항에 대해 계속 설명합니다.

유형 삭제는 또한 생성자 또는 메서드의 시그니처를 매개 변수화된 유형 또는 유형 변수가 없는 시그니처에 매핑합니다.생성자 또는 메서드 시그니처의 삭제s는, 같은 되어 있는 시그니처입니다.s 에 되어 있는 모든 s.

메서드 또는 컨스트럭터의 시그니처가 지워지면 메서드의 반환 타입과 범용 메서드 또는 컨스트럭터의 타입 파라미터도 삭제됩니다.

범용 메서드의 시그니처 삭제에는 유형 파라미터가 없습니다.

다음 버그 리포트에는 컴파일러 개발자인 Maurizio Cimadamore와 JLS의 저자 중 한 명인 Alex Buckley가 이러한 동작이 발생하는 이유에 대해 몇 가지 의견이 포함되어 있습니다.https://bugs.openjdk.java.net/browse/JDK-6400189. (요컨대 사양을 단순화합니다.)


안전하지 않다면 왜 raw 타입을 사용할 수 있습니까?

다음은 JLS 4.8의 다른 인용문입니다.

raw 타입의 사용은 레거시 코드의 호환성에 대한 양보를 위해서만 허용됩니다.Java 프로그래밍 언어에 일반성이 도입된 후 작성된 코드에서 원시 유형을 사용하는 것은 강력히 권장되지 않습니다. 향후 Java 프로그래밍 언어 버전에서는 raw 유형의 사용이 금지될 수 있습니다.

유효한 Java 2nd Edition에는 다음과 같은 기능도 있습니다.

raw 활자를 사용해서는 안 되는데, 왜 언어 설계자들이 이를 허용했을까요?호환성을 제공합니다.

Java 플랫폼은 제네릭스가 도입된 2년차에 접어들기 직전이었고 제네릭스를 사용하지 않는 엄청난 양의 Java 코드가 존재했다.이 모든 코드가 합법적이고 제네릭스를 사용하는 새로운 코드와 상호 운용 가능한 상태로 유지되는 것이 중요하다고 간주되었습니다.매개 변수화된 유형의 인스턴스를 일반 유형과 함께 사용하도록 설계된 메서드에 전달하는 것은 합법적이어야 하며, 그 반대의 경우도 마찬가지입니다.이행 호환성이라고 불리는 이 요건은 로우 타입을 지원하는 결정을 내리게 되었습니다.

요약하자면, raw 유형은 새 코드에서 절대 사용하지 마십시오.항상 매개 변수화된 유형을 사용해야 합니다.


예외는 없나요?

유감스럽게도 Java 제네릭은 비인증이기 때문에 새로운 코드에서 raw 유형을 사용해야 하는 두 가지 예외가 있습니다.

  • 래스스alsalsals, ::):List.class 아니라, 이에요.List<String>.class
  • instanceof operand:o instanceof Set 아니라, 이에요.o instanceof Set<String>

「 」를 참조해 주세요.

Java에서 raw type은 무엇이며, 왜 새로운 코드에 사용하지 말라는 말을 자주 듣습니까?

원시 유형은 자바 언어의 고대 역사입니다.처음에는 있었다.Collections 그들은 리리를 열었다.Objects그 이상도 이하도 아니다.Collections필필 from casts 의 필수 캐스팅Object이치노

List aList = new ArrayList();
String s = "Hello World!";
aList.add(s);
String c = (String)aList.get(0);

이 방법은 대부분의 경우 작동했지만 오류가 발생했습니다.

List aNumberList = new ArrayList();
String one = "1";//Number one
aNumberList.add(one);
Integer iOne = (Integer)aNumberList.get(0);//Insert ClassCastException here

오래된 타입리스 컬렉션은 타입 안전성을 강제할 수 없었기 때문에 프로그래머는 컬렉션에 저장한 것을 기억해야 했다.
이 제한을 회피하기 위해 개발된 제네릭스에서 개발자는 저장된 유형을 한 번 선언하고 대신 컴파일러가 이를 수행합니다.

List<String> aNumberList = new ArrayList<String>();
aNumberList.add("one");
Integer iOne = aNumberList.get(0);//Compile time error
String sOne = aNumberList.get(0);//works fine

비교용:

// Old style collections now known as raw types
List aList = new ArrayList(); //Could contain anything
// New style collections with Generics
List<String> aList = new ArrayList<String>(); //Contains only Strings

더 복잡한 Comparable 인터페이스:

//raw, not type save can compare with Other classes
class MyCompareAble implements CompareAble
{
   int id;
   public int compareTo(Object other)
   {return this.id - ((MyCompareAble)other).id;}
}
//Generic
class MyCompareAble implements CompareAble<MyCompareAble>
{
   int id;
   public int compareTo(MyCompareAble other)
   {return this.id - other.id;}
}

, 이 경우 하다는 점에 해 주십시오.CompareAblecompareTo(MyCompareAble):"CHANGE: " "CHANGE: "CHANGE:

  • 의 ★★★★Object에 저장되어 있다Collection할 수 .
  • 제네릭을 사용하면 컴파일 시간 체크가 가능
  • 하는 것은 각을 raw로 하는 것과 .Object

컴파일러의 기능:제네릭은 하위 호환성이 있으며 원시 유형과 동일한 Java 클래스를 사용합니다.마법은 대부분 컴파일 시간에 발생합니다.

List<String> someStrings = new ArrayList<String>();
someStrings.add("one");
String one = someStrings.get(0);

다음과 같이 컴파일됩니다.

List someStrings = new ArrayList();
someStrings.add("one"); 
String one = (String)someStrings.get(0);

이것은 raw 타입을 직접 사용하는 경우와 같은 코드입니다.그 일이 어떻게 될지 잘 모르겠다고 생각했는데CompareAble2개의 2개의 2개의 2개의 가 생성됩니다.compareTo은 「」, 1은 「1」, 1은 「1」,MyCompareAble그리고 다른 하나는Object등등등등 1 、 등 1 등

raw 타입의 대체 수단에는 무엇이 있습니까?범용 기기 사용

raw 타입은 타입 인수가 없는 범용 클래스 또는 인터페이스의 이름입니다.예를 들어 일반 Box 클래스가 지정됩니다.

public class Box<T> {
    public void set(T t) { /* ... */ }
    // ...
}

하려면 , 「」를 합니다.Box<T>의 형식 타입 「」에 , 「T:

Box<Integer> intBox = new Box<>();

raw type type raw type은 raw type입니다.Box<T>:

Box rawBox = new Box();

therefore그 、Box 타입의 입니다.Box<T>단, 일반적이지 않은 클래스 또는 인터페이스 타입은 원시 타입이 아닙니다.

많은 API 클래스(Collections 클래스 등)가 JDK 5.0 이전 버전의 범용이 아니었기 때문에 레거시 코드에 원시 유형이 표시됩니다.타입을 으로 raw 즉 raw 타입의 동작을 얻을 수 .Box 주다Objects.을 위해 할 수 . 하위 호환성을 위해 매개변수화된 유형을 원시 유형에 할당할 수 있습니다.

Box<String> stringBox = new Box<>();
Box rawBox = stringBox;               // OK

그러나 raw 유형을 매개 변수화된 유형에 할당하면 다음과 같은 경고가 표시됩니다.

Box rawBox = new Box();           // rawBox is a raw type of Box<T>
Box<Integer> intBox = rawBox;     // warning: unchecked conversion

raw 유형을 사용하여 대응하는 범용 타입에 정의되어 있는 범용 메서드를 호출하는 경우에도 경고가 표시됩니다.

Box<String> stringBox = new Box<>();
Box rawBox = stringBox;
rawBox.set(8);  // warning: unchecked invocation to set(T)

경고는 원시 유형이 일반 유형 검사를 바이패스하므로 안전하지 않은 코드 캐치가 런타임으로 지연됩니다.따라서 raw 타입의 사용은 피해야 합니다.

Java 컴파일러가 원시 유형을 사용하는 방법에 대한 자세한 내용은 "유형 삭제" 섹션을 참조하십시오.

선택되지 않은 오류 메시지

앞서 설명한 바와 같이 레거시 코드를 범용 코드와 혼합하면 다음과 같은 경고 메시지가 표시될 수 있습니다.

주의: Example.java는 체크되지 않은 조작 또는 안전하지 않은 조작을 사용합니다.

참고: -Xlint:상세 확인 안 함으로 다시 컴파일합니다.

이 문제는 다음 예시와 같이 raw 타입으로 동작하는 오래된 API를 사용하는 경우에 발생할 수 있습니다.

public class WarningDemo {
    public static void main(String[] args){
        Box<Integer> bi;
        bi = createBox();
    }

    static Box createBox(){
        return new Box();
    }
}

'체크되지 않음'이란 컴파일러에 충분한 타입 정보가 없기 때문에 타입의 안전성을 확보하기 위해 필요한 모든 타입 체크를 실행할 수 없음을 의미합니다.컴파일러가 힌트를 제공하지만 기본적으로 "체크되지 않음" 경고는 비활성화되어 있습니다.모든 "선택되지 않은" 경고를 보려면 -Xlint:선택되지 않은 상태로 다시 컴파일하십시오.

-Xlint:체크박스를 끄고 이전 예를 다시 컴파일하면 다음과 같은 추가 정보가 나타납니다.

WarningDemo.java:4: warning: [unchecked] unchecked conversion
found   : Box
required: Box<java.lang.Integer>
        bi = createBox();
                      ^
1 warning

체크되지 않은 경고를 완전히 비활성화하려면 -Xlint:-체크되지 않은 플래그를 사용합니다.@SuppressWarnings("unchecked")주석을 지정하면 선택되지 않은 경고가 억제됩니다.★★★★★★★★★★★★★에 익숙하지 않은 경우@SuppressWarnings문문을구

원본 출처: Java 튜토리얼

Java에서 "raw" 유형은 일반적이지 않고 안전한 일반 유형 매개 변수가 아닌 "raw" 개체를 처리하는 클래스입니다.

예를 들어 Java 제네릭스를 사용할 수 있게 되기 전에는 다음과 같은 컬렉션 클래스를 사용합니다.

LinkedList list = new LinkedList();
list.add(new MyObject());
MyObject myObject = (MyObject)list.get(0);

목록에 개체를 추가할 때 개체 유형은 상관 없으며 목록에서 개체를 가져올 때 원하는 유형으로 명시적으로 개체를 캐스팅해야 합니다.

목록에서 사용할 수 있는 개체 유형을 명시적으로 지정해야 하므로 제네릭스를 사용하여 "알 수 없는" 요소를 제거합니다.

LinkedList<MyObject> list = new LinkedList<MyObject>();
list.add(new MyObject());
MyObject myObject = list.get(0);

Generics에서는 Get Call에서 객체를 캐스팅할 필요가 없습니다.콜렉션은 MyObject에서만 동작하도록 미리 정의되어 있습니다.바로 이 사실이 제네릭스의 주요 원동력이다.런타임 오류의 원인을 컴파일 시 확인할 수 있는 것으로 변경합니다.

 private static List<String> list = new ArrayList<String>();

유형 매개 변수를 지정해야 합니다.

경고는 제네릭을 지원하도록 정의된 유형을 원시 형식을 사용하는 대신 매개 변수화해야 한다고 조언합니다.

List는 제네릭을되어 있습니다.public class List<E>이것에 의해, 컴파일시에 체크되는 많은 타입 세이프 조작이 가능하게 됩니다.

raw 타입이란 무엇이며, 새로운 코드에 사용하면 안 된다는 말을 자주 듣는 이유는 무엇입니까?

type된 유형에 대해 인수를 하지 않고 예를 들어 type"은 "raw type"을 사용합니다.ListList<String>Java에 제네릭이 도입되었을 때 제네릭을 사용하기 위해 여러 클래스가 업데이트되었습니다.이러한 클래스를 (type 인수를 지정하지 않고) "raw type"으로 사용하면 레거시 코드를 계속 컴파일할 수 있습니다.

"Raw type"은 하위 호환성을 위해 사용됩니다.type 인수와 함께 범용 클래스를 사용하면 더 강력한 입력이 가능해져 코드 이해성이 향상되고 잠재적인 문제가 더 빨리 발견될 수 있으므로 새 코드에서의 사용은 권장되지 않습니다.

생활자를 사용할 수 없다면 대체 방법은 무엇이며, 어떻게 하면 좋을까요?

인수 「」등를 지정하고, 목적대로 범용 .List<String>이를 통해 프로그래머는 보다 구체적으로 유형을 지정할 수 있으며 변수 또는 데이터 구조의 의도된 사용에 대해 미래의 유지관리자에게 더 많은 의미를 전달할 수 있으며 컴파일러는 더 나은 유형 안전성을 적용할 수 있습니다.이러한 장점이 결합하면 코드 품질이 향상되고 코딩 오류가 발생하는 것을 방지할 수 있습니다.

예를 들어 프로그래머가 'names'라는 목록 변수에 문자열만 포함되도록 하는 메서드의 경우:

List<String> names = new ArrayList<String>();
names.add("John");          // OK
names.add(new Integer(1));  // compile error

여기에서는 개념을 명확히 할 수 있는 여러 사례를 검토하고 있습니다.

1. ArrayList<String> arr = new ArrayList<String>();
2. ArrayList<String> arr = new ArrayList();
3. ArrayList arr = new ArrayList<String>();

케이스 1

ArrayList<String> arr그것은 이다ArrayList이 「」인 .String가 「」를 하고 있는가.ArralyList의 오브젝트String 할 수 String type Object는 오브젝트 타입입니다.

은 엄밀한 것이다Stringraw type raw 타입.

    arr.add("hello");// alone statement will compile successfully and no warning.

    arr.add(23);  //prone to compile time error.
     //error: no suitable method found for add(int)

케이스 2

경우, 「 」ArrayList<String> arr이지만 오브젝트입니다.new ArrayList(); typeraw raw 입니다.

    arr.add("hello"); //alone this compile but raise the warning.
    arr.add(23);  //again prone to compile time error.
    //error: no suitable method found for add(int)

(여기서)arrstrict 타 깐깐하다.이렇게 시간 가 발생하게 됩니다.integer.

경고:- ARaw는 Type Object를 .Strict 유형 " " "ArrayList.

케이스 3

경우, 「 」ArrayList arr는 raw 타입입니다.new ArrayList<String>();strict 타 깐깐하다.

    arr.add("hello");  
    arr.add(23);  //compiles fine but raise the warning.

의 오브젝트도 할 수 .왜냐하면 이 오브젝트에는 오브젝트가 포함되어 있기 때문입니다.arr Typeraw 입니다.

경고:- AStrict는 Type Object를 .rawVariable.type referred " 입니다.

컴파일러는 다음과 같이 기술하기를 원합니다.

private static List<String> list = new ArrayList<String>();

그렇지 않으면 타입을 할 수 있기 때문에.list를 '이렇게 하다'로 합니다new ArrayList<String>()이므로 Java를 사용하여 작성는 컴파일 기능입니다.new ArrayList<String>() 받아들이다Integer ★★★★★★★★★★★★★★★★★」JFrame type" "raw type" 에 List오브젝트 자체는 컴파일러만이 포함할 수 있는 타입에 대해 아무것도 모릅니다.

raw type이 당신을 괴롭히는 또 다른 경우가 있습니다.

public class StrangeClass<T> {
  @SuppressWarnings("unchecked")
  public <X> X getSomethingElse() {
    return (X)"Testing something else!";
  }

  public static void main(String[] args) {
    final StrangeClass<String> withGeneric    = new StrangeClass<>();
    final StrangeClass         withoutGeneric = new StrangeClass();
    final String               value1,
                               value2;

    // Compiles
    value1 = withGeneric.getSomethingElse();

    // Produces compile error:
    // incompatible types: java.lang.Object cannot be converted to java.lang.String
    value2 = withoutGeneric.getSomethingElse();
  }
}

원시 유형은 클래스 유형 매개 변수에 바인딩된 메서드에만 영향을 미치지만 실제로는 자체 유형 매개 변수가 있는 일반 메서드에도 영향을 미치기 때문에 이는 직관적이지 않습니다.

승인된 답변에서 설명한 바와 같이 raw 유형의 코드 내에서 제네릭에 대한 모든 지원을 잃게 됩니다.에서는 「」만 ).Object를 참조해 주세요.

raw-type은 범용 타입을 사용할 때 타입 파라미터가 없는 것을 의미합니다.

은 raw-type raw-type 등 수.double로 간주되는 것에 대해서Setints.

Set set = new HashSet();
set.add(3.45); //ok

하다.Set .int s에게 .Integer시 ; ; ; ; ; ;는 입니다.double온다.3.45입니다.

type 파라미터가 에 추가되어 있다.Set이치이 예방적 오류를 통해 런타임 중에 문제가 발생하기 전에 문제를 해결할 수 있습니다(따라서 시간과 노력을 절약할 수 있습니다).

Set<Integer> set = new HashSet<Integer>();
set.add(3.45); //NOT ok.

raw 타입은 피하십시오.

원시 유형은 유형 매개 변수를 지정하지 않고 일반 유형을 사용하는 것입니다.

예를 들어 다음과 같습니다.

A list이지만 raw 타입입니다.List<String>는 파라미터화된 유형입니다.

JDK 1.5에 제네릭이 도입되었을 때 raw 타입은 이전 버전의 Java와의 하위 호환성을 유지하기 위해서만 유지되었습니다.

raw 타입의 사용은 여전히 가능하지만 피해야 합니다.

  • 그들은 보통 깁스를 요구한다.
  • 이러한 오류는 안전한 유형이 아니며 일부 중요한 오류는 실행 시에만 나타납니다.
  • 표현력이 떨어지고 매개 변수화된 유형과 동일한 방식으로 자체 문서화하지 않습니다.

예:

import java.util.*;
public final class AvoidRawTypes {
    void withRawType() {
        //Raw List doesn't self-document, 
        //doesn't state explicitly what it can contain
        List stars = Arrays.asList("Arcturus", "Vega", "Altair");
        Iterator iter = stars.iterator();
        while (iter.hasNext()) {
            String star = (String) iter.next(); //cast needed
            log(star);
        }
    }

    void withParameterizedType() {
        List < String > stars = Arrays.asList("Spica", "Regulus", "Antares");
        for (String star: stars) {
            log(star);
        }
    }

    private void log(Object message) {
        System.out.println(Objects.toString(message));
    }
}
 

참고: https://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html

, 의 무이이 what list는 입니다.List특정되지 않은 객체의 경우. 내에 알수 없습니다.그런 다음 목록을 반복할 때 모든 요소를 캐스팅해야 해당 요소의 속성(이 경우 String)에 액세스할 수 있습니다.

일반적으로 컬렉션을 파라미터화하는 것이 좋습니다.따라서 변환에 문제가 없습니다.파라미터화된 유형의 요소만 추가할 수 있으며 에디터는 선택 가능한 적절한 메서드를 제공합니다.

private static List<String> list = new ArrayList<String>();

튜토리얼 페이지

raw 타입은 타입 인수가 없는 범용 클래스 또는 인터페이스의 이름입니다.예를 들어 일반 Box 클래스가 지정됩니다.

public class Box<T> {
    public void set(T t) { /* ... */ }
    // ...
}

매개 변수화된 Box 유형을 작성하려면 형식 유형 매개 변수 T:에 실제 유형 인수를 지정합니다.

Box<Integer> intBox = new Box<>();

실제 type 인수를 생략한 경우 다음과 같은 미가공 유형의 상자를 만듭니다.

Box rawBox = new Box();

저는 샘플 연습을 몇 번 해보니 똑같은 곤혹스러움을 느꼈습니다.

==============샘플에 따라 이 코드에서 ===============

public static void main(String[] args) throws IOException {

    Map wordMap = new HashMap();
    if (args.length > 0) {
        for (int i = 0; i < args.length; i++) {
            countWord(wordMap, args[i]);
        }
    } else {
        getWordFrequency(System.in, wordMap);
    }
    for (Iterator i = wordMap.entrySet().iterator(); i.hasNext();) {
        Map.Entry entry = (Map.Entry) i.next();
        System.out.println(entry.getKey() + " :\t" + entry.getValue());
    }

====================== 이 코드로 ========================

public static void main(String[] args) throws IOException {
    // replace with TreeMap to get them sorted by name
    Map<String, Integer> wordMap = new HashMap<String, Integer>();
    if (args.length > 0) {
        for (int i = 0; i < args.length; i++) {
            countWord(wordMap, args[i]);
        }
    } else {
        getWordFrequency(System.in, wordMap);
    }
    for (Iterator<Entry<String, Integer>> i = wordMap.entrySet().iterator(); i.hasNext();) {
        Entry<String, Integer> entry =   i.next();
        System.out.println(entry.getKey() + " :\t" + entry.getValue());
    }

}

===============================================================================

그게 더 안전할 수도 있지만 철학을 깨는 데 4시간이 걸렸어요

표현하고 싶은 것을 표현할 때는 생타입이 좋습니다.

를 들어,는 를를음, 음음음음음음음음음음음을 할 수 .List단, 목록의 요소 유형을 인식하지 않습니다. ★★★★★★★★★★★★★★★★★.List여기서 적절한 반환 유형입니다.

언급URL : https://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it

반응형