1.0.0 Summary
Tittle:【Java】-NO.16.EBook.4.Java.1.009-【疯狂Java讲义第3版 李刚】- 泛型
Style:EBook
Series:Java
Since:2017-09-22
End:....
Total Hours:...
Degree Of Diffculty:2
Degree Of Mastery:2
Practical Level:2
Desired Goal:2
Archieve Goal:....
Gerneral Evaluation:...
Writer:kingdelee
Related Links:
http://www.cnblogs.com/kingdelee/
1.泛型
泛型可以使用在类、方法、对象中
1.1 继承泛型
在一个类中,父类显式写明的泛型,子类不能再重复写,只能写子类自己的
// 1. 在一个类中,父类显式写明的泛型,子类不能再重复写,只能写子类自己的
public class A1 extends Apple
{
// 正确重写了父类的方法,返回值
// 与父类Apple的返回值完全相同
public String getInfo()
{
return "子类" + super.getInfo();
}
public T getT(T t){
System.out.println("A1:" + t.toString());
return t;
}
/*
// 下面方法是错误的,重写父类方法时返回值类型不一致
public Object getInfo()
{
return "子类";
}
*/
public static void main(String[] args) {
AA stringIntegerAA = new AA<>();
stringIntegerAA.getT("a");
}
}
class AA extends A1{
@Override
public T getT(T o) {
super.getT(o);
System.out.println("AA:");
return o;
}
}
1.2 泛型不能作为静态对象的申明,不能作为静态方法的形参,但是可以作为静态方法的方法体中的参数使用。
public class R
{
// 下面代码错误,不能在静态变量声明中使用类型形参
//static T info;
T age;
public void foo(T msg){}
// 下面代码错误,不能在静态方法声明中使用类型形参
//public static void bar(T msg){}
// 只能写在void之后,不能写在static之后
//public static void bar(Object msg){}
// 泛型不能作为参数传进来,却能作为方法中的参数来使用
public static void bar(Object msg){ T t = null;}
}
1.3 数组和集合中泛型问题
假设Foo是Bar的子类,G和G之间不存在继承关系,即G不能传给G,但Foo[] 是 Bar[]的子类,Foo[]可以传给Bar[]
3. 泛型通配符
3.1 >使用这种时,他的类型就是Object,往往作为方法中传递的形参使用,而不是申明使用。在做形参使用时,往往与 extends 或者 super来一起使用,限定参数范围。
public void drawAll(List extends Shape> shapes)
{
for (Shape s : shapes)
{
s.draw(this);
}
}
3.2 泛型与通配符
当某个泛型不会作为返回值,也不会被某些参数依赖,则使用通配符更优
3.3 构造器泛型的申明语法,即 new A();
class MyClass {
public MyClass(T t) {
System.out.println("t参数的值为:" + t);
}
}
public class GenericDiamondTest {
public static void main(String[] args) {
// MyClass类声明中的E形参是String类型。
// 泛型构造器中声明的T形参是Integer类型
MyClass mc1 = new MyClass<>(5);
// 显式指定泛型构造器中声明的T形参是Integer类型,
MyClass mc2 = new MyClass(5);
// MyClass类声明中的E形参是String类型。
// 如果显式指定泛型构造器中声明的T形参是Integer类型
// 此时就不能使用"菱形"语法,下面代码是错的。
//MyClass mc3 = new MyClass<>(5);
}
}
3.4 类型推断
// 1.类型推断, A.a();
class MyUtil
{
public static MyUtil nil()
{
return null;
}
public static MyUtil cons(Z head, MyUtil tail)
{
return null;
}
E head()
{
return null;
}
}
public class InferenceTest
{
public static void main(String[] args)
{
// 可以通过方法赋值的目标参数来推断类型参数为String
MyUtil ls = MyUtil.nil();
// 无需使用下面语句在调用nil()方法时指定类型参数的类型
MyUtil mu = MyUtil.nil();
// 可调用cons方法所需的参数类型来推断类型参数为Integer
MyUtil.cons(42, MyUtil.nil());
// 无需使用下面语句在调用nil()方法时指定类型参数的类型
MyUtil.cons(42, MyUtil.nil());
// 希望系统能推断出调用nil()方法类型参数为String类型,
// 但实际上Java 8依然推断不出来,所以下面代码报错
//String s = MyUtil.nil().head();
String s = MyUtil.nil().head();
}
}