Java -- 泛型
来源:互联网 发布:多益网络账号格式错误 编辑:程序博客网 时间:2024/06/06 03:46
1. 泛型: 允许在定义类,接口时指定类型形参,这个类型形参将在声明变量,创建对象时确定(即传入实际的类型参数,也可以成为类型实参)。
如下示例: 可以对泛型形参做限制 class A<T extends C>{}, T就只能是C的子类。可以用extends设置上限,就可以用super设置下限 <? super T>,对应T或者T的父类。
class A<T> // <T>为泛型, 不必在意T的实际类型,这只是一个类型形参{T info;}class B extends A<Double> //泛型类继承的时候需要明确参数类型{}public class Main {public static void main(String[] args) {A<String> a = new A<String>(); //定义变量时 确定泛型类型 为Stringa.info = "hello_world";System.out.println(a.info);B b = new B(); //继承时确定泛型为Doubleb.info = 3.14159;System.out.println(b.info);}}
2. 不管泛型类型的实际类型参数是什么,他们在运行时总是有同样的类,系统中并不会真真生成泛型类。类的静态变量和静态方法在所有实例中共有,所以不能用静态修饰泛型变量。
3. 泛型通配符, 由于有泛型类的存在,所有当泛型类做形参是,有可能并不能确定形参的类型,这时就可以用泛型通配符?。
同时可以限制通配符 void testB(A<? extends C>){} , 这样泛型参数类型就只能是C的子类。
如果Foo是Bar的一个子类,而G是有泛型声明的接口 或者 类,那么G<Foo>并不是G<Bar>的子类。
class A<T>{T info;}class B {void testB(A<?> a) //并不能确定形参的类型,可以用 泛型通配符 ? {System.out.println(a.info);}}public class Main {public static void main(String[] args) {A<String> a1 = new A<String>();A<Double> a2 = new A<Double>();a1.info = "hello_world";a2.info = 3.14159;B b1 = new B();b1.testB(a1);b1.testB(a2);}}
如下:
ArrayList<?> list = new ArrayList<String>();
list.add("hello"); //报错
泛型通配符 只是表示各泛型List的父类,并不能把元素加进去。
4. 泛型方法,在声明时定义一个或多个类型形参,
格式: 修饰符 <T, S > 返回值类型 方法名(形参列表) { 。。。 }
class A<T>{T info;}class B {void testB(A<?> a) //泛型通配符{System.out.println(a.info);}}class C{static <T> void testC(T t) //泛型方法{System.out.println(t);}}public class Main {public static void main(String[] args) {A<String> a1 = new A<String>();A<Double> a2 = new A<Double>();a1.info = "hello_world";a2.info = 3.14159;B b1 = new B();b1.testB(a1);b1.testB(a2);String t1 = new String("hello");Double t2 = new Double(3.14);C.testC(t1);C.testC(t2);}}
从上可以看出 泛型通配符和泛型方法 用法上有很多交集,但如果某个方法中一个形参a的类型依赖于 另一个形参b的类型,则形参b的类型声明不能用通配符。因为b的类型无法确定的话,程序无法定义形参a的类型。
5. 泛型类和反射泛形
public class GenericDao<T> {
private T field1;
public void save(T obj){}
public T getId(int id){}
}
泛形的典型应用:BaseDao和反射泛型:
//基本Daopublic abstract class BaseDao<T> {private Session session;private Class clazz;//哪个子类调的这个方法,得到的class就是子类处理的类型(非常重要)public BaseDao(){Class clazz = this.getClass(); //拿到的是子类ParameterizedType pt = (ParameterizedType) clazz.getGenericSuperclass(); //BaseDao<Category>clazz = (Class) pt.getActualTypeArguments()[0];System.out.println(clazz);}public void add(T t){session.save(t);}public T find(String id){return (T) session.get(clazz, id);}public void update(T t){session.update(t);}public void delete(String id){T t = (T) session.get(clazz, id);session.delete(t);}}
public class BookDao extends BaseDao<Book> {// 子类Dao}
- 【java 2】java泛型
- Java 泛型 Java generic
- Java Tutorials_Generics(java泛型)
- Java基础 Java 泛型
- java 泛型
- java泛型
- Java泛型
- Java泛型
- java泛型
- java泛型
- java泛型
- Java 泛型
- Java泛型
- Java 泛型
- JAVA 泛型
- java 泛型
- java泛型
- Java泛型
- 使用WakeLock使Android应用程序保持后台唤醒
- Linux系列-文件系统基本结构和文件基本操作管理
- 开源游戏学习- 模拟系统的架构设计
- SQL Server 2008编程入门经典笔记(第十四章:事务和锁)
- Linux Memory Policy
- Java -- 泛型
- Ubuntu 配置Goagent
- popupwindow 捕获不到 setTouchInterceptor
- 关于Windows Server 2008 文件夹共享权限设置问题
- springMVC+spring+Ibatis增删改查的demo
- 理解JavaScript的caller,callee,call,apply
- apache的访问控制和虚拟主机的配置
- android 获取文件夹、文件的大小 以B、KB、MB、GB 为单位
- ajax