泛型
1. 泛型是给编译器看的,编译时会将<类型>去掉,叫做去类型化。
所以:
public void hello(List<String> list);
public void hello(List<Integer> list);
编译器认为是同一个方法,不是方法重载,所以上面代码编译时会提示错误。
2. 泛型可以在定义类型时定义,这样所有的成员方法,都可以使用该泛型;
也可以在定义方法时才定义,这样不能方法间的泛型之间就没有关系。
// 定义方法时,定义泛型
在方法签名中定义泛型
public static void main(String[] args)
{
Number number = 10;
Integer integer = 20;
test1(1, 2);
test2(number, 10);
test3(number, 10);
test4(integer, 10);
List<String> list = new ArrayList<String>();
list.add("1");
}
/**
* @param <T> 表示定义了一种新的类型, 默认是继承于Object类型
* @param a 只要是T类型(Object)的实例即可传递
*/
public static <T> void test1(T a, int b){};
/**
* @param <T> 表示定义了一种新的类型, 并且该类型继承于Number
* @param a 只要是T类型的实例即可传递
*/
public static <T extends Number> void test2(T a, int b){};
/**
* @param <T> 表示定义了一种新的类型, 并且该类型继承于Number, 并且实现了Serializable接口
* @param a 只要是T类型的实例即可传递
*/
public static <T extends Number & Serializable> void test3(T a, int b){};
/**
* @param <T> 表示定义了一种新的类型, 并且该类型继承于Number, 并且实现了Serializable和Comparable接口
* @param a 只要是T类型的实例即可传递
* @return T 返回一个T类型的对象
*/
public static <T extends Number & Serializable & Comparable<Integer>> T test4(T a, int b)
{
return null;
};
{
Number number = 10;
Integer integer = 20;
test1(1, 2);
test2(number, 10);
test3(number, 10);
test4(integer, 10);
List<String> list = new ArrayList<String>();
list.add("1");
}
/**
* @param <T> 表示定义了一种新的类型, 默认是继承于Object类型
* @param a 只要是T类型(Object)的实例即可传递
*/
public static <T> void test1(T a, int b){};
/**
* @param <T> 表示定义了一种新的类型, 并且该类型继承于Number
* @param a 只要是T类型的实例即可传递
*/
public static <T extends Number> void test2(T a, int b){};
/**
* @param <T> 表示定义了一种新的类型, 并且该类型继承于Number, 并且实现了Serializable接口
* @param a 只要是T类型的实例即可传递
*/
public static <T extends Number & Serializable> void test3(T a, int b){};
/**
* @param <T> 表示定义了一种新的类型, 并且该类型继承于Number, 并且实现了Serializable和Comparable接口
* @param a 只要是T类型的实例即可传递
* @return T 返回一个T类型的对象
*/
public static <T extends Number & Serializable & Comparable<Integer>> T test4(T a, int b)
{
return null;
};
// 定义类时,定义泛型
定义类的时候定义泛型
/**
* 在类中定义泛型
* @param <E> 定义一种新的类型, 该类型相当于类的私有成员变量, 所以只能在成员方法中使用, 不可以在类方法(static方法)中使用.
*/
interface ICommonDao<E>
{
/**
* 增加一个元素
*/
public E add(E e);
/**
* 删除一个元素
*/
public void delete(E e);
/**
* 修改一个元素
*/
public void update(E e);
/**
* 按ID查询一个元素
*/
public E findById(String id);
/**
* 按照查询条件查询元素集合
*/
public List<E> findByCondition(String where);
/**
* static 方法不能引用前面定义的<E>, 如果要用, 只能在自己的方法签名中定义新的泛型
*/
}
* 在类中定义泛型
* @param <E> 定义一种新的类型, 该类型相当于类的私有成员变量, 所以只能在成员方法中使用, 不可以在类方法(static方法)中使用.
*/
interface ICommonDao<E>
{
/**
* 增加一个元素
*/
public E add(E e);
/**
* 删除一个元素
*/
public void delete(E e);
/**
* 修改一个元素
*/
public void update(E e);
/**
* 按ID查询一个元素
*/
public E findById(String id);
/**
* 按照查询条件查询元素集合
*/
public List<E> findByCondition(String where);
/**
* static 方法不能引用前面定义的<E>, 如果要用, 只能在自己的方法签名中定义新的泛型
*/
}
3. 泛型应用, 使用泛型实现对任意实体对象的增、删、改、查Dao
对任意实例E的操作
/**
* 必须定义成abstract, 否则不能知道E所代表的Class类型
* @param <E> 被操作的实体对象
*/
abstract class CommonDaoImpl<E> implements ICommonDao<E>
{
// 参数化类型E 的class,知道它后,就可以知道具体操作的是什么类型的实现BEAN了。
Class<E> persistentClass;
@SuppressWarnings("unchecked")
public CommonDaoImpl()
{
// 多态代码,其实是调用了子类的getClass()方法,获取父类(CommonDaoImpl<E>)参数化后的真正类型。如CommonDaoImpl<Person>
ParameterizedType pType = (ParameterizedType)getClass().getGenericSuperclass();
// 返回 参数化类型(CommonDaoImpl<E>) 的 实际类型参数(Person).
persistentClass = (Class<E>)pType.getActualTypeArguments()[0];
System.out.println(persistentClass.getName());
}
public E add(E e)
{
return null;
}
public List<E> findByCondition(String where)
{
return null;
}
public E findById(String id)
{
return null;
}
public void delete(E e){}
public void update(E e){}
}
public static void main(String[] args)
{
// 构造一个匿名的CommonDaoImpl实现类
new CommonDaoImpl<Integer>(){};
}
* 必须定义成abstract, 否则不能知道E所代表的Class类型
* @param <E> 被操作的实体对象
*/
abstract class CommonDaoImpl<E> implements ICommonDao<E>
{
// 参数化类型E 的class,知道它后,就可以知道具体操作的是什么类型的实现BEAN了。
Class<E> persistentClass;
@SuppressWarnings("unchecked")
public CommonDaoImpl()
{
// 多态代码,其实是调用了子类的getClass()方法,获取父类(CommonDaoImpl<E>)参数化后的真正类型。如CommonDaoImpl<Person>
ParameterizedType pType = (ParameterizedType)getClass().getGenericSuperclass();
// 返回 参数化类型(CommonDaoImpl<E>) 的 实际类型参数(Person).
persistentClass = (Class<E>)pType.getActualTypeArguments()[0];
System.out.println(persistentClass.getName());
}
public E add(E e)
{
return null;
}
public List<E> findByCondition(String where)
{
return null;
}
public E findById(String id)
{
return null;
}
public void delete(E e){}
public void update(E e){}
}
public static void main(String[] args)
{
// 构造一个匿名的CommonDaoImpl实现类
new CommonDaoImpl<Integer>(){};
}
输出:
java.lang.Integer
Hibernate中的GenericHibernateDAO就是使用这种方式实现对任意类型实体的操作。(http://community.jboss.org/wiki/GenericDataAccessObjects)