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
일반 클래스의 정의에 비해 위의 코드는 클래스 이름 뒤에 전가 매개 변수 (우리가 일반적으로 말하는 매개 변수) 는 소괄호로 둘러싸여 있습니다. 예를 들어 (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;
}
유형 매개변수의 범위
범주에서 유형 매개 변수를 제한하지 않으면 정의된 데이터 형식만 받아들일 수 있다.그러나 많은 경우 우리는 일부 데이터 형식만 있으면 충분하고 사용자가 다른 데이터 형식을 전달하면 오류를 일으킬 수 있다.예를 들어, 다양한 유형의 그룹 (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;
}
여기 extends 키워드는 더 이상 계승의 의미가 아닙니다. T는 Number 클래스에서 계승된 유형이거나 T는 XX 인터페이스를 실현한 유형으로 이해해야 합니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.