1.Java中的基本思想可以用過使用Object這樣的適當的超類實現泛型。基本類型的自動包/拆裝,會是基本類型的包裝類與Object兼容。且自動包/拆裝是編譯器自動內部運行。
public class Test {
public static void main(String[] args) {
System.out.println("ok");
System.out.println("+++++++++++++++++++");
MemoryCell m = new MemoryCell();
m.write("37");//傳入的參數是String
System.out.println("contents are :"+m.read());
MemoryCell m1 = new MemoryCell();
m.write(37);//傳入的參數是int
System.out.println("contents are :"+m.read());
}
}
class MemoryCell{
private Object storedValue;//使用Object實現泛型
public Object read(){
return storedValue;
}
public void write(Object x){
storedValue=x;
}
}
##################################################
Console:
ok
+++++++++++++++++++
contents are :37
contents are :37
2.使用藉口類型實現泛型。當只使用Object類中已有的方法進行操作時,則可以使用Object完成泛型任務。但當需要新的方法,區別Object的方法,則可以使用接口實現泛型。
3.數組中的協變數組類型(covariant array type)保證數組在編譯期間不會出錯,所以下邊的代買在編譯期間不會出錯。但數組要求存儲對象類型一致性,所以下邊代碼在運行期間會出錯。代碼會拋出異常:
public class Test {
public static void main(String[] args) {
person[] ps = new employee[5];//ps數組對象爲emplyee類型
ps[0]=new student();//student類型無法存到employee數組對象中
System.out.println("ok");
}
}
class person{
}
class employee extends person{
}
class student extends person{
}
###Console:###
Exception in thread "main" java.lang.ArrayStoreException: student
at Test.main(Test.java:6)
4.Java5後支持泛型類型,指定泛型類時,在類名後面的一對尖括號內包含一個或者多個類型參數,而在類體中的域或者方法可以使用這些類型參數。如下代碼實現泛型類型:
public class GenericMemoryCell<T> {
private T storedvalue;
public T read(){
return storedvalue;
}
public void write(T x){
storedvalue=x;
}
public static void main(String[] args) {
GenericMemoryCell<String> m = new GenericMemoryCell<String>();
m.write("fdklsjf");
System.out.println(m.read());
GenericMemoryCell<String> m1 = new GenericMemoryCell<String>();//m1指定的類型爲String
m1.write(37);//傳入的是int與指定類型String衝突
System.out.println(m1.read());
}
}
########################################
Console:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The method write(String) in the type GenericMemoryCell<String> is not applicable for the arguments (int)
at GenericMemoryCell.main(GenericMemoryCell.java:16)
6.泛型在編譯期間會檢驗類型。協變類型在編譯期間無法檢驗出錯,所以泛型檢驗可以使用通配符加強在編譯期間的類型檢驗。泛型可以理解爲類型標記,在編譯期間進行處理。而通配符加強了類型之間的父子關係。
import java.awt.List;
import java.util.ArrayList;
import java.util.Collection;
public class WildCard {
public static double totalArea(Collection<? extends Shape> arr){
double total = 0;
for(Shape s:arr){
if(s!=null){
total += s.area;
}
}
return total;
}
public static void main(String[] args) {
WildCard testwildcard = new WildCard();
Collection<Shape> arr = new ArrayList<Shape>();
Shape shape1 = new Shape(23.3);
Shape shape2 = new Shape(34);
arr.add(shape1);
arr.add(shape2);
System.out.println(testwildcard.totalArea(arr));
System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++");
Square square1 = new Square(78);
Square square2 = new Square(34);
Collection<Shape> arr2 = new ArrayList<Shape>();
arr2.add(square1);
arr2.add(square2);
System.out.println(testwildcard.totalArea(arr2));
}
}
class Shape{
double area;
Shape(double area){
this.area=area;
}
}
class Square extends Shape {
Square(double area) {
super(area);
}
}
################################################
Console:
57.3
+++++++++++++++++++++++++++++++++++++++++++++++
112.0
7.泛型方法類似泛型類,因爲兩者的類型參數表都使用相同的語法。在泛型方法中類型參數位於返回類型之前。
public static <T> boolean contains(Collection<T> arr,T x){
for(T val:arr){
if(x.equals(arr)){
return true;
}
}
return false;
}
System.out.println(WildCard.contains(arr, shape1));
System.out.println(WildCard.contains(arr2, square2));
---------------------------------------------------
對泛型類型進行限界(使用extends或者super).編譯器會對泛型進行類型檫除,使用限定的類型替換泛型參數。泛型的好處是程序員不用進行類型轉換而是由編譯器進行類型檢查。
public static<T extends Comparable<? super T>> T findMax(T [] arr){
int maxIndex = 0;
for(int i=1;i<arr.length;i++){
if(arr[i].compareTo(arr[maxIndex])>0){
maxIndex = i;
}
}
return arr[maxIndex];
}
函數對象
import java.util.Comparator;
public class FindMax {
public static <T> T findMax(T[] arr,Comparator<? super T> cmp){
int maxIndex = 0;
for(int i=1;i<arr.length;i++){
if(cmp.compare(arr[i],arr[maxIndex])>0){
maxIndex=i;
}
}
return arr[maxIndex];
}
public static void main(String[] args) {
String [] arr ={"ZEBER","ALLIGATOR","crocodeile"};
System.out.println(findMax(arr,new CasInsensitiveCompare()));
}
}
class CasInsensitiveCompare implements Comparator<String>{
@Override
public int compare(String o1, String o2) {
return o1.compareToIgnoreCase(o2);
}
}
// package java.util
// interface Comparator<T>{
// int compare(T lhs, T ths);
//}