泛型方法
所谓泛型方法,就是带有类型参数的方法,它既可以定义在泛型类中(例如public void show(T aa),在使用泛型上没有任何特殊语法要求),也可以定义在普通类中(需要自定义参数类型,那么把泛型参数放在方法上就可以了,就是放在返回值类型之前,例如public <T> void show(T aa)), 静态方法不能访问类的泛型,如果需要泛型只能在方法上使用泛型,例如public static <T> void show(T aa)
可以写一个泛型方法,该方法在调用时可以接收不同类型的参数。根据传递给泛型方法的参数类型,编译器适当地处理每一个方法调用。
import java.util.Date;
public class Test1 {
public static void main(String[] args) {
A1 a1=new A1();
a1.pp(null);
B1 b1=new B1();
b1.pp("abc");
b1.bb(new Date(),123);
}
}
class A1<T,ID,BB,CC>{
T id;
ID name;
BB age;
CC brith;
public void pp(T t) {
System.out.println("nihao");
}
}
class B1{
public <T> void pp(T t) {
System.out.println(t.toString());
System.out.println(t.hashCode());
System.out.println(t.getClass());
}
public <T extends Comparable<? extends T>,D> void bb(T t,D d) {
t.compareTo(null);
}
public <T> T cc(T t) {
return null;
}
public static void main(String[] args) {
B1 b1=new B1();
b1.pp(123);
b1.pp("abc");
b1.bb(new Date(),123);
}
}
import java.util.Date;
public class Test2 {
@SuppressWarnings({ "unchecked", "rawtypes", "static-access", "unused" })
public static void main(String[] args) {
B2 bb=new B2();
bb.cc(123);
bb.cc("tttt");
B2<String> b2=new B2<>();
// b2.cc(123); //语法报错
b2.cc("123");
b2.bb(123); // 静态方法上的<T>和类上的<T>无关
int kk=b2.dd(123); // dd方法上有<T>声明,则和类上的<T>无关
String ss=b2.dd("abcd");
Date dd=b2.dd(new Date());
}
}
class A2{
public static <T> void pp(T t) {
}
}
class B2<T>{
public void cc(T t) {}
public static <T> T bb(T t) {
return null;
}
@SuppressWarnings("hiding")
public <T> T dd(T t) {
return null;
}
}
具体应用案例
有一个接口IA,但是具体实现类不确定,具体实现类的创建交给配置文件
定义类或者方法时,不能确定所需要的参数类型
标准语法
依托于泛型类的写法
public class MyClass<T>{
public void pp(T id){}
public T abc(String name){}
//不能是静态方法,如果静态则必须声明,而且和类上的T无关
}这种写法如果类已经确定则T的类型全部确定
不依靠泛型类,类有可能是没有泛型类
public class A{
public <T> 返回类型 方法名称(T t){}
如果T有约束则必须使用<T extends IA>,方法可以是静态的,也可以是非静态
}特殊的通配符写法
public void pp(类型<? 约束> 参数名){}
约束可以使用extends和super两种
泛型类的继承
泛型类也是可以继承的,任何一个泛型类都可以作为父类或子类。不过泛型类与非泛型类在继承时的主要区别在于:
- 泛型类的子类必须将泛型父类所需要的类型参数,沿着继承链向上传递。这与构造方法参数必须沿着继承链向上传递的方式类似。
- 子类不是泛型类:需要给父类传递类型常量,如class AA extends A<String>,如果不设置则默认class Aa extends A<Object>
- 子类是泛型类:可以给父类传递类型常量,也可以传递类型变量。如class AA3<E> extends A<E>
如果父类中泛型有约束
public class A1<T extends Serializable> {}
public class B1<D extends Serializable> extends A1<D>{} //声明子类型时在子类上声明约束
可以写成public class B1< D extends Serializable > extends A1{},此时A1中T就是Object类型的
import java.io.Serializable;
public class Test2 {
public static void main(String[] args) {
B2 bb=new B2();
Object ss=bb.pp("djszxsc");
System.out.println(ss);
C2<String> cc=new C2<>();
String s2=cc.pp("adncklvksccs");
System.out.println(s2);
}
}
class A2<T extends Serializable>{
public T pp(T t) {
return t;
}
}
class C2<T extends Serializable> extends A2<T> {
public void cc(T e) {
}
@Override
public T pp(T t) {
return super.pp(t);
}
}
class B2 extends A2{
}
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.Reader;
import java.util.Properties;
public class Test1 {
public static void main(String[] args) throws Exception {
Properties ps=new Properties();
Reader r=new FileReader("abc.properties");
ps.load(r);
String clzName=ps.getProperty("IA");
IA obj=(IA)Class.forName(clzName).newInstance();
obj.pp();
}
}
import java.util.Date;
public class Test3 {
public static void main(String[] args) {
// A3<String> aa=new B3();
// String ss=aa.pp("ddd");
// System.out.println(ss);
B3 bb=new B3();
bb.dd(bb);
bb.pp(bb);
A3 aa=new B3<Date>();
// aa.pp(aa);
A3<String> aa1=new B3<Date>();
aa.pp(aa);
}
}
class A3<T>{
public T pp(T t) {
return t;
}
}
class B3<E> extends A3{
public void dd(E t) {
System.out.println(t);
}
}