【Java】-NO.16.EBook.4.Java.1.009-【疯狂Java讲义第3版 李刚】- 泛型

 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<T> extends Apple<String>
{
    // 正确重写了父类的方法,返回值
	// 与父类Apple<String>的返回值完全相同
	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<String, Integer> stringIntegerAA = new AA<>();
		stringIntegerAA.getT("a");
	}

}

class AA<T, C> extends A1<T>{

	@Override
	public T getT(T o) {
		super.getT(o);
		System.out.println("AA:");
		return o;
	}
}

1.2 泛型不能作为静态对象的申明,不能作为静态方法的形参,但是可以作为静态方法的方法体中的参数使用。

public class R<T>
{
    // 下面代码错误,不能在静态变量声明中使用类型形参
//	static T info;
	T age;
	public void foo(T msg){}
	// 下面代码错误,不能在静态方法声明中使用类型形参
//	public static void bar(T msg){}
	// <T>只能写在void之后,不能写在static之后
//	public <T>static void bar(Object msg){}
	// 泛型不能作为参数传进来,却能作为方法中的参数来使用
	public static <T>void bar(Object msg){ T t = null;}

}

  

1.3 数组和集合中泛型问题

假设Foo是Bar的子类,G<Foo>和G<Bar>之间不存在继承关系,即G<Foo>不能传给G<Bar>,但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<T> A();

class MyClass<E> {
    
    public <T> MyClass(T t) {
        System.out.println("t参数的值为:" + t);
    }
}

public class GenericDiamondTest {
    public static void main(String[] args) {
        // MyClass类声明中的E形参是String类型。
        // 泛型构造器中声明的T形参是Integer类型
        MyClass<String> mc1 = new MyClass<>(5);
        // 显式指定泛型构造器中声明的T形参是Integer类型,
        MyClass<String> mc2 = new <Integer>MyClass<String>(5);
        
        
        // MyClass类声明中的E形参是String类型。
        // 如果显式指定泛型构造器中声明的T形参是Integer类型
        // 此时就不能使用"菱形"语法,下面代码是错的。
//		MyClass<String> mc3 = new <Integer> MyClass<>(5);
    }
}

  

3.4 类型推断

// 1.类型推断, A.<T>a();
class MyUtil<E>
{
    public static <Z> MyUtil<Z> nil()
	{
		return null;
	}
	public static <Z> MyUtil<Z> cons(Z head, MyUtil<Z> tail)
	{
		return null;
	}
	E head()
	{
		return null;
	}
}
public class InferenceTest
{
	public static void main(String[] args)
	{
		// 可以通过方法赋值的目标参数来推断类型参数为String
		MyUtil<String> ls = MyUtil.nil();
		// 无需使用下面语句在调用nil()方法时指定类型参数的类型
		MyUtil<String> mu = MyUtil.<String>nil();
		// 可调用cons方法所需的参数类型来推断类型参数为Integer
		MyUtil.cons(42, MyUtil.nil());
		// 无需使用下面语句在调用nil()方法时指定类型参数的类型
		MyUtil.cons(42, MyUtil.<Integer>nil());

		// 希望系统能推断出调用nil()方法类型参数为String类型,
		// 但实际上Java 8依然推断不出来,所以下面代码报错
//		String s = MyUtil.nil().head();
		String s = MyUtil.<String>nil().head();
	}
}

  

猜你喜欢

转载自www.cnblogs.com/kingdelee/p/7604614.html
今日推荐