[size=large][b]Java之泛型(Generic Type)[/b][/size]
[size=medium][b]一、背景知识[/b][/size]
在面向对象编程中有四个概念:抽象、封装、继承、多态
这四种编程思想在Java中的体现:
1、抽象:接口(Interface)、抽象类
2、封装:用权限关键字控制自身属性对外的访问/继承权限:public、protected、default、private
3、继承:一个类可以继承另一个类的属性或方法。
4、多态:有继承必然有多态。允许子类重写 (overwrite) 父类中的方法。
实现多态的条件:继承、重写、向上转型(父类引用子类的对象 [color=gray][注1][/color])。
[color=gray]注:
①父类引用子类的对象,只能引用到父类中定义的属性或方法(可能已经被子类重写)。
不能引用到子类自己定义的属性和方法。
②子类引用子类对象时,子类则可以调用父类的方法。
[/color]
[size=medium][b]二、"模板与解释器"思想[/b][/size]
Java语言需要编译生成.class文件后才能执行。
所以真正在内存中运行的代码是经过编译后的.class文件。
我们写的.java 文件其实是解释器要进行编译的模板。
那么我们就可以对模板进行各种标注。
Java 的注解(annotation)就是这种"模板"思想的典型应用。
为了让代码更加灵活,Java还提供了可以引用 meta-data 的功能。
什么是 meta-data?就是描述数据的数据。
Java在这方面的应用的体现就是:反射(reflection)、泛型(Generic Type)
利用反射(reflection),我们可以不通过使用new关键字对类产生一个对象来调用类的方法,
而是直接 invoke 一个类的方法。这种思想可以应用为 “面向切面编程”:
可以不通过修改源代码而对源代码的方法在其执行前后增加新的逻辑。(如:日志监控,权限判断)
[size=medium][b]三、泛型的起源[/b][/size]
Java 在JDK1.5 中新增了泛型的功能。
根据《Java编程思想 (第4版)》中的描述,泛型出现的动机在于:
泛型出现的最引人注目的一个原因就是为了创建容器类。
我们经常看到这样的写法:
ArrayList<String> list = new ArrayList<String>();
上述写法告诉编译器:这是一个 String 类型的 list。
只能装载 String 类型的数据。装载别的类型的数据会报错。
[size=medium][b]四、泛型的定义[/b][/size]
类的类型的参数化,就是泛型。
或者说:
类的类型也可以作为参数变量传递给类或类的方法。
什么?又多了一种参数形式?是的。
我们知道 Java 中的方法(method)使用小括号声明参数。
Java 使用尖括号 <> 声明一个泛型。
[size=medium][b]五、泛型的含义[/b][/size]
不同的类其泛型所代表的含义不同。
根据类的实现方法,看泛型所代表的具体含义。
[size=medium][b]六、泛型的实现方法[/b][/size]
[b]1、定义泛型[/b]
Java在[color=olive]类[/color]或[color=olive]类的方法[/color]的声明中,声明一个泛型。多个参数时用逗号隔开。
泛型的声明需要写在类名之后或方法的返回值之前。
泛型的声明,写在类名之后:
泛型的声明,写在方法的返回值之前:
这里说明一下:
1)、为了便于阅读,你会看到在Java中有人使用 T E K V 等字母。
这些对编译器来说都是一样的,可以是任意字母。
T : Type (类型)
E : Element(元素)
K : Key(键)
V : Value(值)
2)、泛型的类型参数只能是引用类型,
不能是原始类型(int,char,double,long等)。
[b]2、?通配符:表示任意类型 [/b]
List<?> barList;
[b]3、?通配符的扩展[/b]
1) 限定上边界:
extends 关键字:表示该类型必须继承了某类
2) 限定下边界
super 关键字:表示该类型必须是某类型的父类
[size=medium][b]七、Java中泛型的形态[/b][/size]
[b]1、泛型接口[/b]
[b]2、泛型类[/b]
[b]3、泛型方法[/b]
-
转载请注明
原文出处:http://lixh1986.iteye.com/blog/2323917
-
[size=medium][b]一、背景知识[/b][/size]
在面向对象编程中有四个概念:抽象、封装、继承、多态
这四种编程思想在Java中的体现:
1、抽象:接口(Interface)、抽象类
2、封装:用权限关键字控制自身属性对外的访问/继承权限:public、protected、default、private
3、继承:一个类可以继承另一个类的属性或方法。
4、多态:有继承必然有多态。允许子类重写 (overwrite) 父类中的方法。
实现多态的条件:继承、重写、向上转型(父类引用子类的对象 [color=gray][注1][/color])。
[color=gray]注:
①父类引用子类的对象,只能引用到父类中定义的属性或方法(可能已经被子类重写)。
不能引用到子类自己定义的属性和方法。
②子类引用子类对象时,子类则可以调用父类的方法。
[/color]
[size=medium][b]二、"模板与解释器"思想[/b][/size]
Java语言需要编译生成.class文件后才能执行。
所以真正在内存中运行的代码是经过编译后的.class文件。
我们写的.java 文件其实是解释器要进行编译的模板。
那么我们就可以对模板进行各种标注。
Java 的注解(annotation)就是这种"模板"思想的典型应用。
为了让代码更加灵活,Java还提供了可以引用 meta-data 的功能。
什么是 meta-data?就是描述数据的数据。
Java在这方面的应用的体现就是:反射(reflection)、泛型(Generic Type)
利用反射(reflection),我们可以不通过使用new关键字对类产生一个对象来调用类的方法,
而是直接 invoke 一个类的方法。这种思想可以应用为 “面向切面编程”:
可以不通过修改源代码而对源代码的方法在其执行前后增加新的逻辑。(如:日志监控,权限判断)
[size=medium][b]三、泛型的起源[/b][/size]
Java 在JDK1.5 中新增了泛型的功能。
根据《Java编程思想 (第4版)》中的描述,泛型出现的动机在于:
泛型出现的最引人注目的一个原因就是为了创建容器类。
我们经常看到这样的写法:
ArrayList<String> list = new ArrayList<String>();
上述写法告诉编译器:这是一个 String 类型的 list。
只能装载 String 类型的数据。装载别的类型的数据会报错。
[size=medium][b]四、泛型的定义[/b][/size]
类的类型的参数化,就是泛型。
或者说:
类的类型也可以作为参数变量传递给类或类的方法。
什么?又多了一种参数形式?是的。
我们知道 Java 中的方法(method)使用小括号声明参数。
Java 使用尖括号 <> 声明一个泛型。
[size=medium][b]五、泛型的含义[/b][/size]
不同的类其泛型所代表的含义不同。
根据类的实现方法,看泛型所代表的具体含义。
[size=medium][b]六、泛型的实现方法[/b][/size]
[b]1、定义泛型[/b]
Java在[color=olive]类[/color]或[color=olive]类的方法[/color]的声明中,声明一个泛型。多个参数时用逗号隔开。
泛型的声明需要写在类名之后或方法的返回值之前。
泛型的声明,写在类名之后:
public class Student<T>{
}
泛型的声明,写在方法的返回值之前:
public static <K,V> void update (K k, V v){
}
这里说明一下:
1)、为了便于阅读,你会看到在Java中有人使用 T E K V 等字母。
这些对编译器来说都是一样的,可以是任意字母。
T : Type (类型)
E : Element(元素)
K : Key(键)
V : Value(值)
2)、泛型的类型参数只能是引用类型,
不能是原始类型(int,char,double,long等)。
[b]2、?通配符:表示任意类型 [/b]
List<?> barList;
[b]3、?通配符的扩展[/b]
1) 限定上边界:
extends 关键字:表示该类型必须继承了某类
public <T extends Comparable<T>> T maximum(T x, T y, T z){
}
2) 限定下边界
super 关键字:表示该类型必须是某类型的父类
public class Student<? super Integer>{
}
[size=medium][b]七、Java中泛型的形态[/b][/size]
[b]1、泛型接口[/b]
public interface Calculator<T> {
public T getNumber();
}
public class NumberCalculator implements Calculator<Number> {
@Override
public Number getNumber(){
return Math.random();
}
}
[b]2、泛型类[/b]
public class Mapper<K, V> {
private K key;
private V value;
public Mapper(K k, V v) {
key = k;
value = v;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
}
[b]3、泛型方法[/b]
public class Printer {
public static <T> void print(T t) {
System.out.println(t);
}
public static <T> void print(T... args) {
for (T t : args) {
System.out.println(t);
}
}
public static void main(String[] args) {
print("Hello, World!");
print('a');
print(123);
print(34.5);
print(true);
print("Hello, World!",'a', 12, 34.45, true);
}
}
-
转载请注明
原文出处:http://lixh1986.iteye.com/blog/2323917
-