一般的类和方法,只能使用具体的类型:要么是基本类型,要么是自定义的类。如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大。----《java Generics FAQ》
多态算是一种泛化机制。例如,将方法的参数类型设为基类,那么该方法就可以接受从这个基类中导出的任何类作为参数。
泛型——java SE5,实现了参数化类型的概念,使代码可以应用于多种类型。
容器类——促成泛型出现的原因。
java SE5之前:
public class Holder2{
private Object a;
public Hodler2(Object a){
this.a=a;
}
public void set(Object a){
this.a=a;
}
public Object get(){
return a;
}
}
Hodler2可以存储任何类型的数据,但是一个Hodler2对象却可以存储多种不同类型的数据。而通常我们只会使用容器来存储一种类型的数据。
泛型的目的之一就是用来指定容器要持有什么类型的数据,而且由编译器来保证类型的正确性。
java SE5之后:
public class Hodler3<T>{
public T a;
public Hodler3(T a){
this.a=a;
}
public void set(T a){
this.a=a;
}
public T get(){
return a;
}
}
将需要使用的类型参数,用尖括号括起,放在类名后面。
1、元组类库
仅一次方法调用就能返回多个对象的决解方法——创建一个对象,用它来持有想要返回的多个对象。
元组——将一组对象直接打包存储于其中的一个单一对象。这个容器对象允许读取其中元素,但是不允许向其中存放新的对象。
2维元组:
public class TwoTuple<A,B>{
public final A first;
public final B second;
public TwoTuple(A a,B b){
first=a;
second=b;
}
public String toString(){
return "("+first+","+second+")";
}
}
如果使用具有不同元素的元组,就强制要求他们另外创建一个新的TwoTuple对象。
使用继承机制实现长度更长的元组
public class ThreeTuple<A,B,C> extends TwoTuple<A,B>{
public final C third;
public ThreeTuple(A a,B b,C c){
super(a,b);
third=c;
}
...
}
使用元组:
static TwoTuple<String,Integer> f(){
return new TwoTuple<String,Integer>("hi",47);
}
2、一个堆栈类
public class LinkedStack<T>{
private static class Node<U>{
U item;
Node<U> next;
Node(){
item=null;
next=null;
}
Node(U item,Node<U> next){
this.item=item;
this.next=next;
}
boolean end(){ //末端哨兵
return item==null&&next==null;
}
}
private Node<T> top=new Node<T>();
public void push(T item){
top=new Node<T>(item,top);
}
public T pop(){
T result=top.item;
if(!top.end())
top=top.next;
return result;
}
}
3、RandomList——每次调用select方法时,他可以随机地选取一个元素
public class RandomList<T>{
private ArrayList<T>storage=new ArrayList<T>();
private Random rand=new Random(47);
public void add(T item){
storage.add(item);
}
public T select(){
return storage.get(rand.nextInt(storage.size()));
}
}
------------------------------------------------------------from:http://lavasoft.blog.51cto.com/62575/18771/-----------------------------------------------------------------------------------
附:java中final的作用——
1、final修饰类——
final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。
2、final方法——
如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。
final方法的使用原因:
把方法锁定,防止任何继承类修改它的意义和实现。
高效。编译器遇到调用final方法时候会转入内嵌机制,大大提高执行效率。
3、final变量——
用final修饰的成员变量表示常量,值一旦给定就无法改变。
4、final参数——
当函数的参数为final时,可以读取不可修改。
注意:final类不能用于修饰构造方法。
父类private成员方法是不能被子类方法覆盖的,因此private类型的方法默认都是final类的。
java中static的作用——
1、static变量
被static修饰的变量称为静态变量或类变量。没被static修饰的变量称为实例变量。两者区别:
静态变量在内存中只有一个拷贝(节省内存),JVM只为静态变量分配一次内存,在加载类的过程中完成静态变量的内存分配。可用类名直接访问,也可通过对象访问(不推荐)。
对于实例变量,每创建一个实例就会为示例分配一次内存,实例变量在内存中有多个拷贝,互不影响。
2、静态方法
静态方法可以通过类名调用,任何实例也可以调用,因此静态方法中不能用this和super关键字。不能直接访问所属类的实例变量和实例方法,只能访问所属类的成员变量和成员方法。
因为static方法独立于任何实例,因此static方法必须被实现,不能时abstract。
3、静态代码块
static代码块也叫静态代码块,不在任何的方法体内,JVM加载类时会执行这些代码块,如果静态代码块有多个,JVM将会按照它们在类中出现的顺序依次执行,每个代码块只会被执行一次。
注意:static变量之前加private修饰,表示这个变量不能在其他类中通过类名直接引用。
4、final+static——“全局变量”
对于变量,表示一旦给值就不能修改,并且通过类名来访问。
对于方法,表示不可覆盖,并且可以通过类名来访问。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------