泛型工作原理
Java中的泛型都是編譯器層面來完成的,在生成的Java字節碼中是不包含任何泛型中的類型信息的。使用泛型時加上的類型參數,會在編譯時被編譯器去掉。也就是說Java中的泛型,只在編譯階段有效。在編譯過程中,正確檢驗泛型結果后,會將泛型的相關信息擦出,並且在對象進入和離開方法的邊界處添加類型檢查和類型轉換的方法。
泛型類
定義的泛型類,就一定要傳入泛型類型實參嗎?並不是這樣,在使用泛型的時候如果傳入泛型實參,則會根據傳入的泛型實參做相應的限制,此時泛型才會起到本應起到的限制作用。如果不傳入泛型類型實參的話,在泛型類中使用泛型的方法或成員變量定義的類型可以為任何的類型。
package generic;
public class MyClass<T,E> {
private T object;
public T getObject() {
return object;
}
public void setObject(T object) {
this.object = object;
}
public static void main(String[] args) {
MyClass<String,Integer> myclass = new MyClass<String,Integer>();
myclass.setObject("費哥6666");
System.out.println(myclass.getObject());
}
}
泛型接口
package MyGenerator;
public interface MyGeneric<T> {
T getObejct();
void setObject(T object);
}
當實現泛型接口的類,未傳入泛型實參時:需要在聲明類的時候,需將泛型的聲明也一起加到類中。
package MyGenerator;
public class ChildOne<T> implements MyGeneric<T>{
@Override
public T getObejct() {
return null;
}
@Override
public void setObject(T object) {
System.out.println(6666);
}
}
當實現泛型接口的類,傳入泛型實參時:則所有使用泛型的地方都要替換成傳入的實參類型。
package MyGenerator;
public class ChildTwo implements MyGeneric<String>{
@Override
public String getObejct() {
return null;
}
@Override
public void setObject(String object) {
}
}
泛型通配符"?"
package MyGenerator;
public class ChildTwo<T>{
public String name;
public ChildTwo(String name) {
this.name = name;
}
}
public class Test {
public static String getObejct(ChildTwo<?> child) {
System.out.println(child.name);
return null;
}
public static void main(String[] args) {
ChildTwo<String> one = new ChildTwo<String>("fei");
ChildTwo<Integer> two = new ChildTwo<Integer>("666");
getObejct(one);
getObejct(two);
}
}
結果:
fei
666
泛型方法
泛型類,是在實例化類的時候指明泛型的具體類型;泛型方法,是在調用方法的時候指明泛型的具體類型 ,泛型方法能使方法獨立於類而產生變化。
public <E> void say(ChildTwo<E> child) {
String name = child.name;
System.out.println(name);
}
泛型方法的上下邊界
在泛型方法中添加上下邊界限制的時候,必須在權限聲明與返回值之間的
public <T extends Number> void showKeyName(Generic<T> container){
System.out.println("container key :" + container.getKey());
}
public <T super Number> void showKeyName(Generic<T> container){
System.out.println("container key :" + container.getKey());
}