Java의 범주에 대해 자세히 설명합니다.

10288 단어 Java범용
우리는 변수를 사용하기 전에 변수를 정의하고 정의할 때 그 변수의 데이터 형식, 어떤 데이터 형식이 어떤 값에 부여되는지 알려야 한다는 것을 안다.
만약 우리가 지금 좌표를 표시하기 위해 클래스를 정의하려고 한다면, 좌표의 데이터 형식은 정수, 소수, 문자열일 수 있다. 예를 들어

x = 10、y = 10
x = 12.88、y = 129.65
x = " 180 "、y = " 210 "
서로 다른 데이터 유형에 대해 방법을 빌려 다시 불러오는 것 외에 자동 포장과 상향 전환도 할 수 있다.우리는 기본 데이터 유형이 자동으로 포장되어 대응하는 포장류로 전환될 수 있다는 것을 안다.Object는 모든 클래스의 조상 클래스로, 모든 클래스의 실례는 Object 유형으로 전환할 수 있습니다. 예를 들어 다음과 같습니다.
int --> Integer --> Object
double -->Double --> Object
String --> Object
이렇게 하면 하나의 방법만 정의하면 모든 유형의 데이터를 수신할 수 있다.다음 코드를 참조하십시오.

public class Demo {
  public static void main(String[] args){
    Point p = new Point();
    p.setX(10); // int -> Integer -> Object
    p.setY(20);
    int x = (Integer)p.getX(); //  
    int y = (Integer)p.getY();
    System.out.println("This point is:" + x + ", " + y);
    
    p.setX(25.4); // double -> Integer -> Object
    p.setY(" 180 ");
    double m = (Double)p.getX(); //  
    double n = (Double)p.getY(); //  
    System.out.println("This point is:" + m + ", " + n);
  }
}
class Point{
  Object x = 0;
  Object y = 0;
  public Object getX() {
    return x;
  }
  public void setX(Object x) {
    this.x = x;
  }
  public Object getY() {
    return y;
  }
  public void setY(Object y) {
    this.y = y;
  }
}
위의 코드에서 좌표를 생성할 때 아무런 문제가 없지만 좌표를 꺼낼 때 아래로 전환해야 한다. 자바 다태적 대상의 유형 전환에서 우리는 아래로 전환하는 데 위험이 존재하고 컴파일하는 동안 쉽게 발견하지 못하며 실행 기간에만 이상을 던질 수 있기 때문에 아래로 전환하는 것을 최대한 피해야 한다고 말했다.위의 코드를 실행하면 12번째 줄에서java를 던집니다.lang. ClassCastException 예외입니다.
그렇다면 재부팅 (중복 코드) 을 사용하지 않고 위험을 최소화할 수 있는 더 좋은 방법은 없을까?
예. 범용 클래스(Java Class)를 사용할 수 있으며 모든 유형의 데이터를 수용할 수 있습니다.이른바'범용형'은 바로'광범위한 데이터 유형'으로 임의의 데이터 유형이다.
위의 코드를 변경하고 범용 클래스를 사용합니다.

public class Demo {
  public static void main(String[] args){
    //  
    Point<Integer, Integer> p1 = new Point<Integer, Integer>();
    p1.setX(10);
    p1.setY(20);
    int x = p1.getX();
    int y = p1.getY();
    System.out.println("This point is:" + x + ", " + y);
    
    Point<Double, String> p2 = new Point<Double, String>();
    p2.setX(25.4);
    p2.setY(" 180 ");
    double m = p2.getX();
    String n = p2.getY();
    System.out.println("This point is:" + m + ", " + n);
  }
}
//  
class Point<T1, T2>{
  T1 x;
  T2 y;
  public T1 getX() {
    return x;
  }
  public void setX(T1 x) {
    this.x = x;
  }
  public T2 getY() {
    return y;
  }
  public void setY(T2 y) {
    this.y = y;
  }
}
실행 결과:

This point is:10, 20
This point is:25.4,  180 
일반 클래스의 정의에 비해 위의 코드는 클래스 이름 뒤에 , T1, T2는 사용자 정의 식별자이자 매개 변수로 데이터를 전달하는 형식이지 데이터의 값이 아니다. 우리는 유형 매개 변수라고 부른다.범형에서 데이터의 값은 파라미터를 통해 전달할 수 있을 뿐만 아니라 데이터의 유형도 파라미터를 통해 전달할 수 있다.T1, T2는 데이터 형식의 자리 표시자일 뿐, 실행할 때 진정한 데이터 형식으로 대체됩니다.
전가 매개 변수 (우리가 일반적으로 말하는 매개 변수) 는 소괄호로 둘러싸여 있습니다. 예를 들어 (int x, double y), 유형 매개 변수 (범용 매개 변수) 는 뾰족한 괄호로 둘러싸여 있고, 여러 매개 변수는 쉼표로 구분됩니다. 예를 들어 또는 .
유형 매개 변수는 클래스 이름 뒤에 제시해야 합니다.일단 유형 파라미터를 주면 클래스에서 사용할 수 있습니다.유형 매개 변수는 반드시 합법적인 식별자여야 한다. 습관적으로 하나의 대문자를 사용해야 한다. 일반적인 상황에서 K는 키, V는 값을 나타내고 E는 이상이나 오류를 나타내며 T는 일반적인 의미의 데이터 형식을 나타낸다.
범용 클래스는 실례화할 때 반드시 구체적인 유형, 즉 유형 매개 변수에 값을 전달해야 한다. 형식은 다음과 같다.

  className variable<dataType1, dataType2> = new className<dataType1, dataType2>();
등호 오른쪽의 데이터 유형을 생략할 수도 있지만 다음과 같은 경고가 발생합니다.

  className variable<dataType1, dataType2> = new className();
범용 클래스를 사용할 때 데이터 유형을 가리키기 때문에 다른 유형에 부여된 값은 이상을 던진다. 아래로 전환할 필요도 없고 잠재적인 위험도 없기 때문에 본고가 처음에 소개한 자동 포장과 상향 전환보다 더욱 실용적이다.
참고:
범주형은 Java 1.5의 새로운 특성으로 C++ 템플릿을 참조하고 본질은 매개 변수화 유형(Parameterized Type)의 응용이다.
형식 매개 변수는 인용 형식만 표시할 수 있고 int,double,char 등 기본 형식을 표시할 수 없습니다.그러나 전달의 기본 유형은 틀리지 않는다. 왜냐하면 그들은 자동으로 포장류로 포장되기 때문이다.
범용 방법
범용 클래스를 정의하는 것 외에도 플롯 좌표의 범용 방법을 정의할 수 있습니다.

public class Demo {
  public static void main(String[] args){
    //  
    Point<Integer, Integer> p1 = new Point<Integer, Integer>();
    p1.setX(10);
    p1.setY(20);
    p1.printPoint(p1.getX(), p1.getY());
    
    Point<Double, String> p2 = new Point<Double, String>();
    p2.setX(25.4);
    p2.setY(" 180 ");
    p2.printPoint(p2.getX(), p2.getY());
  }
}
//  
class Point<T1, T2>{
  T1 x;
  T2 y;
  public T1 getX() {
    return x;
  }
  public void setX(T1 x) {
    this.x = x;
  }
  public T2 getY() {
    return y;
  }
  public void setY(T2 y) {
    this.y = y;
  }
  
  //  
  public <T1, T2> void printPoint(T1 x, T2 y){
    T1 m = x;
    T2 n = y;
    System.out.println("This point is:" + m + ", " + n);
  }
}
실행 결과:

This point is:10, 20
This point is:25.4,  180 
위의 코드에는 일반적인 매개 변수도 있고 형식 매개 변수도 있습니다. 형식 매개 변수는 수식자 뒤에 놓고 값 형식 앞에 되돌려야 합니다.유형 매개 변수를 정의하면 매개 변수 목록, 방법체, 반환 값 형식에서 사용할 수 있습니다.
범용 클래스를 사용하는 것과 달리 범용 방법을 사용할 때 매개 변수 유형을 가리킬 필요가 없으며, 컴파일러는 전달된 매개 변수에 따라 자동으로 구체적인 유형을 찾아낸다.범용 방법은 정의가 다른 것을 제외하고는 일반적인 방법과 같다.
주의: 범용 방법은 범용 클래스와 필연적인 관계가 없고 범용 방법은 자신의 유형 파라미터가 있기 때문에 일반 클래스에서도 범용 방법을 정의할 수 있다.범용 방법 printPoint()의 유형 매개 변수 T1, T2는 범용 클래스 Point의 T1, T2와 필연적인 관계가 없으며 다른 식별자로 대체할 수 있습니다.

public static <V1, V2> void printPoint(V1 x, V2 y){
  V1 m = x;
  V2 n = y;
  System.out.println("This point is:" + m + ", " + n);
}
범용 인터페이스
Java에서도 범용 인터페이스를 정의할 수 있습니다. 여기서 더 이상 설명하지 않고 예제 코드만 제시합니다.

public class Demo {
  public static void main(String arsg[]) {
    Info<String> obj = new InfoImp<String>("www.weixueyuan.net");
    System.out.println("Length Of String: " + obj.getVar().length());
  }
}
// 
interface Info<T> {
  public T getVar();
}
// 
class InfoImp<T> implements Info<T> {
  private T var;
  //  
  public InfoImp(T var) {
    this.setVar(var);
  }
  public void setVar(T var) {
    this.var = var;
  }
  public T getVar() {
    return this.var;
  }
}
실행 결과:

Length Of String: 18
유형 삭제
범주를 사용할 때 데이터 유형을 지정하지 않으면 범주를 삭제합니다. 다음 코드를 보십시오.

public class Demo {
  public static void main(String[] args){
    Point p = new Point(); //  
    p.setX(10);
    p.setY(20.8);
    int x = (Integer)p.getX(); //  
    double y = (Double)p.getY();
    System.out.println("This point is:" + x + ", " + y);
  }
}
class Point<T1, T2>{
  T1 x;
  T2 y;
  public T1 getX() {
    return x;
  }
  public void setX(T1 x) {
    this.x = x;
  }
  public T2 getY() {
    return y;
  }
  public void setY(T2 y) {
    this.y = y;
  }
}
실행 결과:

This point is:10, 20.8
범주를 사용할 때 데이터 형식을 가리키지 않기 때문에 오류가 발생하지 않도록 컴파일러는 모든 데이터를 Object로 전환하기 때문에 좌표를 꺼내서 사용할 때 아래로 전환해야 한다. 이것은 본고가 범주를 사용하지 않았던 것과 다름없다.
범용 유형 제한
위의 코드에서 형식 매개 변수는 정의된 데이터 형식을 받아들일 수 있습니다.그러나 많은 경우 우리는 일부 데이터 형식만 있으면 충분하고 사용자가 다른 데이터 형식을 전달하면 오류를 일으킬 수 있다.예를 들어, 다양한 유형의 그룹 (Integer 그룹, Double 그룹, Character 그룹 등) 에서 최대 값을 반환하는 범용 함수를 작성합니다.

public <T> T getMax(T array[]){
  T max = null;
  for(T element : array){
    max = element.doubleValue() > max.doubleValue() ? element : max;
  }
  return max;
}
위의 코드는 오류를 보고합니다.double Value () 는 Number 클래스의 방법입니다. 모든 클래스에 이 방법이 있는 것은 아닙니다. 따라서 우리는 유형 매개 변수 T를 제한하여 Number와 그 하위 클래스 (Integer, Double, Character 등) 만 받아들일 수 있도록 해야 합니다.
extends 키워드를 통해 일반적인 형식을 제한하고 위의 코드를 개선할 수 있습니다.

public <T extends Number> T getMax(T array[]){
  T max = null;
  for(T element : array){
    max = element.doubleValue() > max.doubleValue() ? element : max;
  }
  return max;
}
는 T가 Number와 그 하위 클래스만 받아들이고 다른 유형의 데이터를 전송하면 오류가 발생합니다.여기 한정 사용 키워드 extends, 뒤에 클래스도 인터페이스도 있습니다.그러나 이곳의 extends는 이미 계승의 의미가 아니다. T는 Number 클래스에서 계승된 유형이거나 T는 XX 인터페이스를 실현한 유형으로 이해해야 한다.
유형 매개변수의 범위
범주에서 유형 매개 변수를 제한하지 않으면 정의된 데이터 형식만 받아들일 수 있다.그러나 많은 경우 우리는 일부 데이터 형식만 있으면 충분하고 사용자가 다른 데이터 형식을 전달하면 오류를 일으킬 수 있다.예를 들어, 다양한 유형의 그룹 (Integer 그룹, Double 그룹 등) 에서 최대 값을 반환하는 범용 함수를 작성합니다.

public <T> T getMax(T array[]){
  T max = null;
  for(T element : array){
    max = element.doubleValue() > max.doubleValue() ? element : max;
  }
  return max;
}
위의 코드는 오류를 보고합니다.double Value () 는 Number 클래스와 그 하위 클래스의 방법입니다. 모든 클래스에 이 방법이 있는 것은 아닙니다. 따라서 우리는 유형 매개 변수 T를 제한하여 Number와 그 하위 클래스 (Integer, Double, Character 등) 만 받아들일 수 있도록 해야 합니다.
extends 키워드를 통해 일반적인 유형의 상한선을 제한하고 위의 코드를 개선할 수 있습니다.

public <T extends Number> T getMax(T array[]){
  T max = null;
  for(T element : array){
    max = element.doubleValue() > max.doubleValue() ? element : max;
  }
  return max;
}
는 T가 Number와 그 하위 클래스만 받아들이고 다른 유형의 데이터를 전송하면 오류가 발생합니다.여기 한정 사용 키워드 extends, 뒤에 클래스도 인터페이스도 있습니다.클래스라면 하나밖에 없다.그러나 인터페이스는 여러 개가 있고 "&"로 구분할 수 있습니다. 예를 들어 입니다.
여기 extends 키워드는 더 이상 계승의 의미가 아닙니다. T는 Number 클래스에서 계승된 유형이거나 T는 XX 인터페이스를 실현한 유형으로 이해해야 합니다.

좋은 웹페이지 즐겨찾기