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);
//}