Java学习6之泛型
1.泛型定义
1.泛型类:
public class Generic <T>{ public void get(T t){ System.out.println(t); } }
example:
public class Generic <T> { public void get(T t){ System.out.println(t); } public static void main(String[] args){ Generic <String> generic = new Generic <String>(); generic.get("hello"); Generic <Light> genericOne = new Generic <Light>(); genericOne.get(new Light()); } } class Light{ }
声明范性:使用<>括号,里面写上一个范型的名称T,它仅仅是一个名称,不代表任何类型,在整个类的作用范围内都可以使用T这种范型类型。
使用泛型:声明时要明确T所代表的类型,否则编译不通过。上例声明时,一个支持了String,一个支持了Light类型,get函数的参数T也立刻变成了支持上述类型。因为Generic<T>都是在声明的时候将T替换为具体的类型。
notes:泛型就是一种不针对任何具体类型的类型,它是泛泛的类型,极度不具体的类型,所以也就没有具体的可以使用的服务。
可以看出get函数里面根本无法使用T参数中的服务,只是简单的打印。即使在运行过程中可以支持任何类型,但是在设计期却无法预知具体类型,所以使用泛型时,看到的程序通常都是针对泛型T的定义、转换、动态创建等通用代码,也正因为泛型T没有具体服务,这样的代码才非常通用,但为了达到良好的实用性,在设计上也相对复杂。
example:
泛型类型只能通过强制转型才能使用。
public class Generic <T>{ public void get(T t){ if(t instanceof Light){ Light light = (Light) t; light.on(); } } public static void main(String[] args){ Generic <String> generic = new Generic <String>(); generic.get("hello"); Generic <Light> genericOne = new Generic <Light>(); genericOne.get(new Light()); } } class Light{ public void o(){ System.out.println("light on"); } }
2.泛型接口
public interface Generic <A,B>{ public A get(); }
example:
public class Client{ public void show(GenericInterface genericInterface){ System.out.println(gerericInterface.get().getClass().getName()); } public static void main(String[] args){ Client client = new Client(); client.show(new ConcreteObjectOne<String>("hello")); } } interface GenericInterface<T>{ T get(); } class ConcreteObjectOne <H> implements GenericInterface <H>{ private H t; public ConcreteObjectOne(H t){ this.t = t; } public H get(){ return t; } }
show函数在调用过程中,接收的ConcreteObjectOne在实例化时明确了泛型类型为String,所以ConcreteObjectOne的构造函数立刻变味了以String为参数的构造函数。
2.泛型函数
public class Generic{ public <B> void get(B b){ } }
泛型函数的使用和普通的函数没有任何区别。
generic.get("hello");
generic.get(1);
generic.get(new Light());
泛型函数在使用时,感觉它是一个被无限次重载的函数,支持所有的类型。通常使用泛型的地方都可以使用接口来登记啊实现,因为接口也是一种极度抽象的、不具体的、没有任何实现的,同时也不限制类的继承关系的弱侵入性类型。
3.泛型的边界
由于泛型没有任何服务,如果能够基于一个接口或者类来约束它的类型,那样就可以具有一些需要的服务了。
example:
public class GenericTest<T extends Service>{ public static void main(String[] args){ GenericTest<Service> genericTest = new GenericTest<Service>(); genericTest.callService(new ConcreteService()); } public void callService(T t){ t.print(); } } class ConcreteService implements Service{ public void print(){ System.out.println("print service"); } } interface Service { void print(); }
通过extends关键字达到了类似继承的效果,这种语法约束了泛型的服务范围,只能是Service类型,它使泛型的通用型有了一定的限制,但是增加了可用性。
实际上,这样的代码使事情复杂化了,直接讲callService函数的参数变为接口Service,使用传统的编程方法更简单。
example:
使用接口编程可以替换泛型边界限制
public class GenericTest{ public static void main(String[] args){ GenericTest genericTest = new GenericTest(); genericTest.callService(new ConcreteService()); } public void callService(Service t){ t.print(); } }
example:
多个泛型边界限制
public class GenericTest <T extends Service & ServiceInterfaceOne & ServiceInterfaceTwo>{ public static void main(String[] args){ GenericTest <ConcreteService> genericTest = new GenericTest<ConcreteService>(); genericTest.callService(new ConcreteService()); } public void callService(T t){ t.write(); t.print(); t.show(); } } class ConcreteService extends Service implements ServiceInterfaceOne,ServiceInterfaceTwo{ public void write(){ System.out.println("print service"); } public void print(){ System.out.println("service interface one print"); } public void show(){ System.out.println("service interface two show"); } } class Service{ void write(){ System.out.println("service write"); } } interface ServiceInterfaceOne{ void print(); } interface ServiceInterfaceTwo{ void show(); }
通过类似继承和实现的方式限制了泛型的边界,就可以按照泛型的边界类型调用相应的函数实现具体的逻辑代码,这里的设计依然可以使用传统编程方法替换,会更直观。
4.简单的集合类
public class CollectionTest{ public static void main(String[] args){ SimpleCollection collection = new SimpleCollection(5); //测试自动扩展性 for(int i = 0;i < 65; i++){ collection.add("hello"+i); } System.out.println(collection.size()); System.out.println(collection.delete(10)); System.out.println(collection.delete(30)); System.out.println(collection.delete(40)); //测试边界 collection.add(61,"bad"); collection.add(62,"good"); //测试边界扩展性 collection.add(64,"good1"); collection.add(64,"good2"); //测试边界 collection.add("good3"); //测试边界 System.out.println(collection.delete(collection.size()-1)) //测试打印 System.out.println(collection); //测试自动收缩性 for(int i = 0;i<30;i++){ collection.delete(0); } System.out.println(collection); //测试get System.out.println(collection.get(23)); System.out.println(collection.size()); } } interface Collection{ void add(Object item); void add(int index,Object item); Object delete(int index); Object get(int index); int size(); } class SimpleCollection implements Collection{ //自动扩展的大小 private static final int AUTO_INC_SIZE = 20; //集合容器 private Object[] array; //集合中有效对象的数量 private int size; //初始化制定大小容器 public SimpleCollection(int size){ array = new Object[size]; this.size = 0; } //默认大小容器 public SimpleCollection(){ array = new Object[AUTO_INC_SIZE]; this.size = 0; } //在末尾添加对象 public void add(Object item){ add(size,item); } //在指定位置插入对象 public void add(int index,Object item){ if(index>size) throw new ArrayIndexOutOfBoundsException("超出索引:"+index+"最大:"+(size-1)); //有效对象数量超出容器大小,自动扩充容器 if(array.length == size){ Object[] result = new Object[array.length + AUTO_INC_SIZE]; for(int i = 0;i<= array.length;i++){ if(i<index){ result[i] = array[i]; }else if(i>index){ result[i] = array[i-1]; } } result[index] = item; array = result; }else{ //插入位置后的对象整体后移 for(int i = size;i>index;i--){ array[i] =array[i-1]; } array[index] = item; } size++; }
//删除指定位置对象
public Object delete(int inde){
if(index>size-1)
throw new ArrayIndexOutOfBoundsException("超出索引:"+index+",最大:"+(size-1));
Object delObject = null;
//无效对象过多,容器自动收缩
if(array.length-size>AUTO_INC_SIZE * 2){
Object[] result = new Object[size+ AUTO_INC_SIZE];
for(int i = 0;i<size;i++){
if(i < index){
result[i] = array[i];
}
if(i>index)
result[i-1] = array[i];
}
size--;
delObject = array[index];
array = result;
}
//删除位置后对象前移
if(index<size){
for(int i = index;i<size;i++){
if((i+1)<array.length)
array[i] = array[i+1];
}
//移动后清楚末尾无用对象
array[size-1] = null;
size--;
return array[index];
}
return delObject;
}
public Object get(int index){
if(index<size){
return array[index];
}
throw new ArrayIndexOutOfBoundsException("超出索引:"+index+",最大:"+(size-1));
}
public int size(){
return size;
}
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("[");
for(int i = 0;i<size;i++){
sb.append(array[i]);
if(i<size-1)
sb.append(",");
}
sb.append("]");
return sb.toString();
} }
这个集合是使用了最基本的数组进行实现。可以学习到数组的使用、元素的福祉和

浙公网安备 33010602011771号