java泛型机制

泛型:实现了参数化的概念,使代码可以运用与多种类型。

泛型的主要目的之一就是用来指定容器要持有什么类型的对象,而且由编译器保证类型的正确性。

public class Holder<T> {
private T a;
public Holder(T a) {
	this.a=a;
}
public void set(T a) {
	this.a=a;
}
public T get() {
	return a;
}
public static void main(String[] args) {
	Holder<String> h=new Holder<String>("string");
	String b=h.get();
	//h.set(1); 通不过编译器
}
}

元组类库

概念:它是将一组对象直接打包存储于其中一个单一对象,这个容器对象允许读取其中元素,但不允许向其中存放新的对象。

public class TwoTuple<A,B> {
public final A first;//创建之后不能再创建
public final B second;
public TwoTuple(A a,B b) {
	first=a;
	second=b;
}
@Override
public String toString() {
	return "TwoTuple [first=" + first + ", second=" + second + "]";
}
}

用继承增加长度

class ThreeTuple<A,B,C> extends TwoTuple<A,B>{
	public final C third;
	public ThreeTuple(A a,B b,C c) {
		super(a,b);
		this.third=c;
	}
}

泛型接口

泛型可以应用于接口,例如生成器,这是一种专门负责创建对象的类

public interface Generator<T>{T next();}

接口的实现

public class Fibonacci implements Generator<Integer>{
private int count=0;

	@Override
	public Integer next() {
		// TODO Auto-generated method stub
		return fib(count++);
	}
private int fib(int n) {
	if(n<2) return 1;
	return fib(n-2)+fib(n-1);//递归
}
public static void main(String[] args) {
	Fibonacci gen=new Fibonacci();
	for(int i=0;i<10;i++) {
		System.out.print(gen.next()+" ");
	}
}
}

在这里插入图片描述
注意基本数据类型无法作为类型参数,但可以使用包装类。

泛型方法

要定义与使用泛型方法只需将参数列表置于返回值之前

public class GenericMethod {
public <T>void f(T x){
	System.out.println(x.getClass().getSimpleName());
}
public static void main(String[] args) {
	GenericMethod gm=new GenericMethod();
	gm.f("");
	gm.f(1);
	gm.f(1.0);
	gm.f(1.0f);
	gm.f(gm);
	
}
}

java泛型机制_第1张图片
类型推断:编译器会为我们找出具体类型。

可变参数列表与泛型方法

import java.util.*;
//
public class GeneriVarargs {
public static <T> List<T> makelist(T... args){
	List<T> result=new ArrayList<T>();
	for(T item:args) {
		result.add(item);
	}
	return result;
}
public static void main(String[] args) {
	List<String> is=makelist("A");
	System.out.println(is);
	is=makelist("A","B","C");
	System.out.println(is);
	is=makelist("ABCDEFGHIJKLMN".split(""));
	System.out.println(is);
}
}

java泛型机制_第2张图片

擦除

import java.util.*;
//
class Frob{};
class Fnorkle{};
class Quark<Q>{};
class Particle<M,N>{};
//
public class LostInformation {
public static void main(String[] args) {
	List<Frob> list=new ArrayList<Frob>();
	Map<Frob,Fnorkle> map=new HashMap<>();
	Quark<Fnorkle> quark=new Quark<Fnorkle>();
	Particle<Long,Double> p=new Particle<>();
	//
	System.out.println(Arrays.toString(list.getClass().getTypeParameters()));
	System.out.println(Arrays.toString(map.getClass().getTypeParameters()));
	System.out.println(Arrays.toString(quark.getClass().getTypeParameters()));
	System.out.println(Arrays.toString(p.getClass().getTypeParameters()));
}
}

Class.getTypeParameters()将返回一个TypeVariable对象的数组,表示所声明的类型参数。
输出:
java泛型机制_第3张图片

因此在泛型代码的内部,无法获得任何有关泛型的参数类型信息。

所以当再使用泛型时,任何具体的类型信息都会被擦除,List<“String”>与List<“Integer”>都会被擦除成为他们的原生类型,即List。

import java.util.*;
//
public class ErasedTypeEquivalence {
  public static void main(String[] args) {
    Class c1 = new ArrayList<String>().getClass();
    Class c2 = new ArrayList<Integer>().getClass();
    System.out.println(c1 == c2);
  }
} /* Output:
true
*///:~

你可能感兴趣的:(笔记)