자바 제네릭


Java 제네릭은 JDK 5에 도입된 새로운 기능입니다. 제네릭은 프로그래머가 컴파일 타임에 잘못된 유형을 감지할 수 있도록 하는 컴파일 타임 유형 안전 감지 메커니즘을 제공합니다.


제네릭의 본질은 매개변수화된 유형입니다. 즉, 연산되는 데이터 유형이 매개변수로 지정된다는 의미입니다.

정수 배열, 문자열 배열 또는 다른 유형의 배열을 정렬할 수 있는 정렬 방법을 작성하는 요구 사항이 있다고 가정해 보겠습니다. 이를 구현하는 방법은 무엇입니까?

답은 Java Generics을 사용할 수 있다는 것입니다.

Java 제네릭 개념을 사용하여 객체 배열을 정렬하는 제네릭 메서드를 작성할 수 있습니다. 그런 다음 이 일반 메서드를 호출하여 정수 배열, 부동 소수점 배열, 문자열 배열 등을 정렬합니다.


일반 메서드

호출 시 다양한 유형의 매개변수를 받을 수 있는 일반 메서드를 작성할 수 있습니다. 일반 메서드에 전달된 매개 변수 유형에 따라 컴파일러는 각 메서드 호출을 적절하게 처리합니다.

다음은 일반 메서드 정의 규칙입니다.

  • 모든 일반 메서드 선언에는 메서드 반환 형식(아래 예 <E>) 앞에 오는 형식 매개 변수 선언 부분(꺾쇠 괄호로 구분)이 있습니다.

  •               각 유형 매개변수 선언 부분에는 쉼표로 구분된 하나 이상의 유형 매개변수가 포함되어 있습니다. 유형 변수라고도 하는 일반 매개변수는 일반 유형의 이름을 지정하는 식별자입니다.

  •               유형 매개변수는 반환 값 유형을 선언하는 데 사용될 수 있으며 일반 메서드에서 얻은 실제 매개변수 유형에 대한 자리 표시자 역할을 할 수 있습니다.

  •               제네릭 메서드 본문의 선언은 다른 메서드와 동일합니다. 유형 매개변수는 기본 유형(예: int, double, char 등)이 아닌 참조 유형만 나타낼 수 있습니다.

예제

다음 예는 일반 메서드를 사용하여 다양한 문자열의 요소를 인쇄하는 방법을 보여줍니다.

public class GenericMethodTest
{
   // 泛型方法 printArray                         
   public static < E > void printArray( E[] inputArray )
   {
      // 输出数组元素            
         for ( E element : inputArray ){        
            System.out.printf( "%s ", element );
         }
         System.out.println();
    }

    public static void main( String args[] )
    {
        // 创建不同类型数组: Integer, Double 和 Character
        Integer[] intArray = { 1, 2, 3, 4, 5 };
        Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
        Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };

        System.out.println( "整型数组元素为:" );
        printArray( intArray  ); // 传递一个整型数组

        System.out.println( "\n双精度型数组元素为:" );
        printArray( doubleArray ); // 传递一个双精度型数组

        System.out.println( "\n字符型数组元素为:" );
        printArray( charArray ); // 传递一个字符型数组
    } 
}

위 코드를 컴파일하면 실행 결과는 다음과 같습니다.

整型数组元素为:
1 2 3 4 5 

双精度型数组元素为:
1.1 2.2 3.3 4.4 

字符型数组元素为:
H E L L O

제한된 유형 매개변수:

다음이 있을 수 있습니다. 때로는 유형 매개변수에 전달될 수 있는 유형의 범위를 제한하고 싶을 수도 있습니다. 예를 들어, 숫자에 대해 작동하는 메서드는 Number의 인스턴스나 Number의 하위 클래스만 허용하기를 원할 수 있습니다. 이것이 제한된 유형 매개변수의 목적입니다.

제한된 유형 매개변수를 선언하려면 먼저 유형 매개변수의 이름을 나열하고 그 뒤에 확장 키워드를 나열하고 마지막으로 상한값을 나열합니다.

다음 예는 "확장"(클래스) 또는 "구현"(인터페이스)을 의미하기 위해 "확장"이 일반적인 의미로 어떻게 사용되는지 보여줍니다. 이 예제의 일반 메서드는 비교 가능한 세 개체의 최대값을 반환합니다.

public class MaximumTest
{
   // 比较三个值并返回最大值
   public static <T extends Comparable<T>> T maximum(T x, T y, T z)
   {                     
      T max = x; // 假设x是初始最大值
      if ( y.compareTo( max ) > 0 ){
         max = y; //y 更大
      }
      if ( z.compareTo( max ) > 0 ){
         max = z; // 现在 z 更大           
      }
      return max; // 返回最大对象
   }
   public static void main( String args[] )
   {
      System.out.printf( "%d, %d 和 %d 中最大的数为 %d\n\n",
                   3, 4, 5, maximum( 3, 4, 5 ) );
 
      System.out.printf( "%.1f, %.1f 和 %.1f 中最大的数为 %.1f\n\n",
                   6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 ) );
 
      System.out.printf( "%s, %s 和 %s 中最大的数为 %s\n","pear",
         "apple", "orange", maximum( "pear", "apple", "orange" ) );
   }
}

위 코드를 컴파일하면 실행 결과는 다음과 같습니다.

3, 4 和 5 中最大的数为 5

6.6, 8.8 和 7.7 中最大的数为 8.8

pear, apple 和 orange 中最大的数为 pear

일반 클래스

일반 클래스 선언은 유형 매개변수 선언 부분이 클래스 이름 뒤에 추가된다는 점을 제외하면 제네릭이 아닌 클래스 선언과 유사합니다.

일반 메소드와 마찬가지로 일반 클래스의 유형 매개변수 선언 부분에도 쉼표로 구분된 하나 이상의 유형 매개변수가 포함되어 있습니다. 유형 변수라고도 하는 일반 매개변수는 일반 유형의 이름을 지정하는 식별자입니다. 이러한 클래스는 하나 이상의 매개변수를 허용하므로 매개변수화된 클래스 또는 매개변수화된 유형이라고 합니다.

예제

다음 예는 일반 클래스를 정의하는 방법을 보여줍니다.

public class Box<T> {
   
  private T t;

  public void add(T t) {
    this.t = t;
  }

  public T get() {
    return t;
  }

  public static void main(String[] args) {
    Box<Integer> integerBox = new Box<Integer>();
    Box<String> stringBox = new Box<String>();

    integerBox.add(new Integer(10));
    stringBox.add(new String("php中文网"));

    System.out.printf("整型值为 :%d\n\n", integerBox.get());
    System.out.printf("字符串为 :%s\n", stringBox.get());
  }
}

위 코드를 컴파일하면 실행 결과는 다음과 같습니다.

整型值为 :10

字符串为 :php中文网