DevOps

Java 101 : 필수 Java 언어 기능 둘러보기, 1 부-3장 assertions and generics

IT오이시이 2017. 6. 14. 14:03
728x90
JAVA 101: THE NEXT GENERATION

Java 101: The essential Java language features tour, Part 1-3

Java programming with assertions and generics


http://www.javaworld.com/article/2071216/learn-java/article.html?page=3



'extends'다음에 유형 이름을 지정하여 와일드 카드의 상한을 제공 할 수 있습니다. 마찬가지로 super에 유형 이름을 지정하여 와일드 카드의 하한을 제공 할 수 있습니다. 이 경계는 실제 유형 인수로 전달 될 수있는 유형을 제한합니다.

'extends'다음에 유형 이름을 지정하여 와일드 카드의 상한을 제공 할 수 있습니다. 마찬가지로 super에 유형 이름을 지정하여 와일드 카드의 하한을 제공 할 수 있습니다. 이 경계는 실제 유형 인수로 전달 될 수있는 유형을 제한합니다.

이 예에서 '<? String> '을'String '또는 하위 클래스가되는 실제 형식 인수로 확장합니다. 마찬가지로, '<? super String> '을'String '또는 수퍼 클래스가되는 실제 유형 인수로 사용합니다. 'String'은 'final'이므로 '확장'할 수 없으므로 'String'객체의 소스 목록과 'String'또는 'Object'객체의 대상 목록 만 전달할 수 있습니다. 그리 유용하지는 않습니다.

유형 일반화 된 구현을 사용하는 클래스 또는 인스턴스 메소드 인 일반 메소드를 사용하여이 문제점을 완전히 해결할 수 있습니다. 일반 메소드 선언은 다음 구문을 준수합니다.

<formalTypeParameterList> returnType
identifier(parameterList)

제네릭 메서드의 형식 형식 매개 변수 목록은 반환 형식 앞에옵니다. 유형 매개 변수와 선택적 상한으로 구성됩니다. 형식 매개 변수는 반환 형식으로 사용할 수 있으며 매개 변수 목록에 나타날 수 있습니다.

Listing 9는 제네릭 copy()메소드 를 선언하고 호출하는 방법을 보여준다.

Listing 9. GenDemo.java (버전 5)

import java.util.ArrayList;
import java.util.List;

public class GenDemo
{
   public static void main(String[] args)
   {
      List<Integer> grades = new ArrayList<Integer>();
      Integer[] gradeValues =
      {
         new Integer(96),
         new Integer(95),
         new Integer(27),
         new Integer(100),
         new Integer(43),
         new Integer(68)
      };
      for (int i = 0; i < gradeValues.length; i++)
         grades.add(gradeValues[i]);
      List<Integer> failedGrades = new ArrayList<Integer>();
      copy(grades, failedGrades, new Filter<Integer>()
                                 {
                                    public boolean accept(Integer grade)
                                    {
                                       return grade.intValue() <= 50;
                                    }
                                 });
      for (int i = 0; i < failedGrades.size(); i++)
         System.out.println(failedGrades.get(i));
   }

   static <T> void copy(List<T> src, List<T> dest,
Filter<T> filter)
   {
      for (int i = 0; i < src.size(); i++)
         if (filter.accept(src.get(i)))
            dest.add(src.get(i));
   }
}

interface Filter<T>
{
   boolean accept(T o);
}

Listing 9에서는 <T> void copy(List<T> src, List<T> dest, Filter<T> filter)일반적인 메소드 를 선언했다 . 컴파일러는 노트의 각각의 타입이 srcdest및 filter매개 변수는 입력 매개 변수를 포함한다 T. 즉, 메소드 호출 중에 동일한 실제 유형 인수가 전달되어야하며 컴파일러는 호출을 검토하여이 인수를 유추합니다.

Listing 9 ( javac GenDemo.java) 를 컴파일 하고 애플리케이션 ( java GenDemo)을 실행하면 다음과 같은 결과가 나온다.

27
43

Java 언어의 제네릭에 대해 논쟁의 여지가있는 것은 무엇입니까?

제네릭은 논란의 여지가 없겠지만, 자바 언어로 구현 된 것은 사실이다. generics는 캐스트를 제거하기위한 구문 적 설탕에 해당하는 컴파일 타임 기능으로 구현되었습니다. 컴파일러는 소스 코드를 컴파일 한 후에 제네릭 형식 또는 제네릭 메서드의 형식 형식 매개 변수 목록을 버립니다. 이 "버림"동작을 삭제라고 합니다. 제네릭에서의 지우기의 다른 예는 코드가 유형이 올바르지 않을 때 적절한 유형에 캐스트를 삽입하고 형식 매개 변수를 상한 (예 :)으로 대체하는 것 Object입니다.

더 일반적인 generics 논쟁

제네릭은 지우개 이외의 이유로 논란의 여지가 있습니다. StackOverflow.com 주제를 참조하십시오. " 왜 일부 Java는 generics 구현이 좋지 않다고 주장합니까? "와일드 카드가 혼동을 줄 수 있다는 제안과 제네릭이 값 유형을 지원하지 않는다는 사실 (예 : 지정할 수 없음 List<int>) 을 비롯한 더 많은 논의가 필요 합니다.

삭제를 사용하면 몇 가지 제한 사항이 발생합니다.

  • 한 가지 예외를 제외하고 instanceof연산자는 매개 변수화 된 유형과 함께 사용할 수 없습니다. 예외는 제한되지 않은 와일드 카드입니다. 예를 들어, 지정할 수 없습니다 Set<Shape> shapes = null; if (shapes instanceof ArrayList<Shape>) {}. 대신 instanceof표현식을 로 변경해야합니다 shapes instanceof ArrayList<?>.이 표현식은 제한없는 와일드 카드를 보여줍니다. 또는 shapes instanceof ArrayList원시 유형 (기본 사용)을 나타내는 방법을 지정할 수 있습니다 .
  • 컴파일러는 일반 코드를 클래스 파일에 저장되는 비 제너릭 코드로 변환합니다. 일부 개발자는 지우기가 클래스 파일에 존재하지 않는 제네릭 정보를 얻기 위해 리플렉션을 사용하지 못하게한다는 지적했습니다. " Java Reflection : Generics "개발자 Jakob Jenkov는 제네릭 정보가 클래스 파일에 저장되는 몇 가지 사례를 지적하며,이 정보는 반사적으로 액세스 할 수 있습니다.
  • 배열 생성 식에는 형식 매개 변수를 사용할 수 없습니다. 예를 들면 elements = new E[size];generic array creation그렇게하려고하면 컴파일러에서 오류 메시지 를보고합니다 .

지우개의 한계를 감안할 때 왜 제네릭이 지워지는지 궁금해 할 것입니다. 그 이유는 간단합니다. Java 컴파일러는 지우기를 사용하도록 리팩터링되어 일반 코드가 일반적인 것이 아닌 레거시 Java 코드와 상호 운용 될 수 있습니다. 이전 버전과의 호환성이 없으면 레거시 Java 코드는 제네릭을 지원하는 Java 컴파일러에서 컴파일되지 않습니다.

1 부 결론

Java 언어는 많은 새로운 기능을 추가하여 발전했습니다. 이 기사에서는 코드의 정확성에 대한 자신감을 높이기 위해 어설 션을 사용하는 방법과 generics를 사용하여 코드를 제거하는 방법을 설명했습니다 ClassCastException. assertion과 generics를 사용하면 런타임시 코드 오류를 최소화하고 화를 잘내는 클라이언트를 처리하는 것과 관련된 두통을 피할 수 있습니다.

Java 5는 Java 플랫폼의 역사에서 중추적 인 역할을했으며 제네릭은 다른 기능보다 논란이 많았지 만 더 중요하지는 않았습니다. 다음 기사에서는 Java 5의 언어에 추가 된 두 가지 필수 기능인 typesafe enums 및 annotation을 소개합니다. 그때까지는 이 기사 의 소스 코드 를 확인하자. 여기에는 어설 션 및 제네릭 프로그래밍에 대한 팁과 예제가 포함되어있다.

Jeff Friesen은 Java 및 Android에 중점을 둔 프리랜서 교사이자 소프트웨어 개발자입니다. Jeff는 Apress 용 Java 및 Android 서적을 작성하는 것 외에도 JavaWorld, informIT , Java.net , DevSource 및 SitePoint 에 대한 Java 및 기타 기술에 대한 수많은 기사를 작성했습니다 . Jeff는 그의 웹 사이트 인 TutorTutor.ca 를 통해 연락 할 수 있습니다 .

이 주제에 대해 자세히 알아보기

  • 이 기사소스 코드 를다운로드하자.
  • Java 언어의 제네릭에 대한 풍부한 정보와 관점에 대한 Angelika Langer의 Java Generics FAQ 를 읽어보십시오 .
  • Java 언어와 그 논쟁의 학생들을 위해, Langer의 " 클로저 토론에 대한 반론"(JavaWorld, 2008 년 6 월)은 Java 7에서 클로저 또는 람다 표현식을 추가하기위한 3 가지 초기 제안을 Java 7에서 비교합니다.
  • 제네릭의 리플렉션 및 런타임에 제네릭 정보에 액세스 할 수있는 특별한 경우에 대한 자세한 내용은 " Java Reflection : Generics "(Jakob Jenkov, Jenkov.com)를 참조하십시오 .
  • Java 101의 추가 정보 : 차세대 :
    • 고통없이 Java 동시성, Part 1 (2013 년 6 월) : Executor 프레임 워크, 동기화 기 유형 및 Java 동시 콜렉션 패키지를 소개합니다.
    • Part 2 (2013 년 8 월) : 잠금, 원자 변수 및 분기 / 결합 조작과 Java 8의 변경 사항에 대한 개요를 소개합니다 java.util.concurrent.
    • Java Date and Time API (2013 년 4 월) : Java 8의 JSR 310 : 날짜 및 시간 API 를 소개하고 필요한 java.time클래스를 직접 실습 할 수 있습니다.
  • JavaWorld의 Java Collections Framework에 대한 추가 정보 :


728x90
반응형