Java의 범용 상세 정보

6822 단어 Java범용
이른바 범주형: 정의 클래스, 인터페이스에서 유형 인자를 지정할 수 있도록 하는 것이다. 이 유형 인자는 변수를 설명하고 대상을 만들 때 확정된다(즉 실제 유형 인자를 전달하거나 유형 실삼이라고 할 수 있다).
범용 클래스 또는 인터페이스
마름모꼴 구문

//
 
public interface List<E> extends Collection<E> 
 
public class HashMap<K,V> extends AbstractMap<K,V>  implements Map<K,V>, Cloneable, Serializable
//
 
List<String> list = new ArrayList();
 
//Java7
 
List<String> list = new ArrayList<>();
범형류에서 자식류를 파견하다

// 1
 
public class App extends GenericType<String>
 
// 2
 
public class App<T> extends GenericType<T>
 
// 3
 
public class App extends GenericType
위범형
진정한 범용 클래스는 존재하지 않는다. 범용 클래스는 자바 가상 컴퓨터에 투명하다.JVM은 범용 클래스의 존재를 알지 못한다. 다시 말하면 JVM은 범용 클래스를 처리하는 것과 일반 클래스는 별 차이가 없다.따라서 정적 방법, 정적 초기화 블록, 정적 변수에서는 유형 인삼을 사용할 수 없습니다.
- 다음 방법은 모두 잘못된 것입니다

private static T data;
 
static{
 
    T f;
 
}
 
public static void func(){
 
    T name = 1;
 
}
다음 예는 측면에서 범용 클래스가 존재하지 않는다는 것을 검증할 수 있다

public static void main(String[] args){
 
        List<String> a1 = new ArrayList<>();
        List<Integer> a2 = new ArrayList<>(); 
    System.out.println(a1.getClass() == a2.getClass());
 
    System.out.println(a1.getClass());
 
    System.out.println(a2.getClass());
 
}
출력

true
 
class java.util.ArrayList
 
class java.util.ArrayList
유형 와일드카드
우선 명확해야 한다. 만약에 Foo가 Bar의 부류라면 List는 List의 부류가 아니다.Java는 다양한 범용 상위 클래스를 나타내기 위해 "?"를 사용합니다.범용 통배를 나타낸다.List다양한 범용 목록의 상위 클래스를 나타냅니다.이 어댑터가 있는 List 범주는 (set) 요소를 설정할 수 없으며, (get) 요소만 가져올 수 있습니다.프로그램에서 List의 유형을 확인할 수 없으므로 객체를 추가할 수 없습니다.객체는 개체 유형일 수 있습니다.
다음 메서드에서 컴파일 오류가 발생합니다.

List<?> list = new ArrayList<>();
 
list.add(new Object());
아이디어 몇 가지:
1. List 대상은 List 대상으로 사용할 수 없다. 즉, List 클래스는 List 클래스의 하위 클래스가 아니다.
2. 수조와 범형은 다르다. 만약에 Foo가 Bar의 하위 유형(자류 또는 하위 인터페이스)이라고 가정하면 Foo[]는 여전히 Bar[]의 하위 유형이다.그러나 G는 G의 하위 유형이 아닙니다.
3. 다양한 범용 List의 상위 클래스를 표시하기 위해 유형 어댑터를 사용해야 합니다. 유형 어댑터는 물음표(?)입니다.물음표를 유형 실참으로 List 집합에 전달하고 쓰기: List알 수 없는 유형 요소의 List를 의미합니다.이 물음표(?)와일드카드라고 불리며 요소 유형은 모든 유형과 일치할 수 있습니다.
와일드카드 상한선
List은 모든 SuperType 범용 목록의 상위 또는 그 자체를 나타냅니다.어댑터 상한선이 있는 범형은 set 방법이 없고 get 방법만 있습니다.
와일드카드 상한선을 설정하면 다음과 같은 문제를 해결할 수 있습니다. Dog는 Animal 하위 클래스입니다. getSize 방법으로 List에 전송된 개수를 얻을 수 있습니다. 코드는 다음과 같습니다.

abstract class Animal {
    public abstract void run();
}
class Dog extends Animal {
    public void run() {
        System.out.println("Dog run");
    }
}
public class App {
    public static void getSize(List<Animal> list) {
        System.out.println(list.size());
    }
    public static void main(String[] args) {
        List<Dog> list = new ArrayList<>();
        getSize(list); //
    }
}
여기서 프로그래밍이 잘못된 이유는 List 이 List 의 부류가 아니기 때문이다.해결 방안1은 getSize 방법의 중형삼 List을 List을 List, 컴파일이 틀리지 않고 형식 변환도 필요 없습니다.
와일드카드 하한선
List 은 SubType 범용 목록의 하한선을 나타냅니다.어댑터 상한선이 있는 범형은 get 방법이 없고 set 방법만 있습니다.
범용 방법
만약 정의 클래스, 인터페이스가 유형 인삼을 사용하지 않았지만 방법을 정의할 때 스스로 유형 인삼을 정의하고 싶다면 이것도 가능하다. JDK1.5는 또한 범용 방법의 지원을 제공했다.범용 방법의 방법 서명은 일반적인 방법의 방법보다 유형 인삼 성명이 많고, 유형 인삼 성명은 뾰족한 괄호로 묶고, 여러 유형 인삼 사이는 쉼표(,)로 구분하며, 모든 유형 인삼 성명은 방법 수식자와 방법 반환값 유형 사이에 놓는다.구문 형식은 다음과 같습니다.

( ){
 
//
 
}
범용 방법은 유형 인삼이 방법의 한 개 이상의 매개 변수 간의 유형 의존 관계를 표시하거나 방법의 반환 값과 매개 변수 간의 유형 의존 관계를 나타낼 수 있도록 허용한다.이런 유형 의존 관계가 없다면 범용 방법을 사용해서는 안 된다.Collections의 copy 방법은 일반적인 방법을 사용합니다.

 public static <T> void copy(List<? super T> dest, List<? extends T> src){ ...}
이 방법은 src 형식은dest 형식의 하위 클래스나 그 자체여야 합니다.
지우기 및 변환
엄격한 범용 코드에서 범용 성명을 가진 클래스는 반드시 유형 파라미터를 가지고 있어야 한다.그러나 오래된 Java 코드와 일치하도록 일반 성명이 있는 클래스를 사용할 때 형식 파라미터를 지정하지 않을 수도 있습니다.이 범용 클래스에 형식 파라미터를 지정하지 않으면, 이 형식 파라미터는 raw type (원시 형식) 라고 불리며, 기본값은 이 파라미터를 설명할 때 지정한 첫 번째 상한 형식입니다.
범용 정보가 있는 대상을 범용 정보가 없는 다른 변수에 부여하면 괄호 사이의 모든 유형 정보가 버려진다.예를 들어 List 유형이 List로 변환되면 이 List는 집합 요소의 유형 검사가 유형 변수의 상한선(즉 Object)으로 바뀌어 삭제됩니다.
예제

class Apple<T extends Number>
 
{
 
 T size;
 
 public Apple()
 
 {
 
 }
 
 public Apple(T size)
 
 {
 
  this.size = size;
 
 }
 
 public void setSize(T size)
 
 {
 
  this.size = size;
 
 }
 
 public T getSize()
 
 {
 
  return this.size;
 
 }
 
}
 
public class ErasureTest
 
{
 
 public static void main(String[] args)
 
 {
 
  Apple<Integer> a = new Apple<>(6);    // ①
 
  // a getSize Integer
 
  Integer as = a.getSize();
 
  // a Apple ,
 
  Apple b = a;      // ②
 
  // b size Number
 
  Number size1 = b.getSize();
 
  //
 
  Integer size2 = b.getSize();  // ③
 
 }
 
}

좋은 웹페이지 즐겨찾기