您的位置:首页 > 编程语言 > Java开发

6 java泛型总结

2017-01-14 16:50 337 查看
1 简介

泛型即“参数化类型”。

自定义泛型接口、泛型类和泛型方法。

泛型类型在逻辑上看似看成是多个不同的类型,实际上都是相同的基本类型。

2 基本用法

1)泛型类

泛型之前使用Object类,但是Object类强制转化为其他类时容易出错。

package javazongjie;

public class Holder<T> {

private T t;

public Holder(T t) {
super();
this.t = t;
}

public T getT() {
return t;
}

public void setT(T t) {
this.t = t;
}

public static void main(String[] args) {
Holder<String> holder = new Holder<>("Hello T!");
System.out.println(holder.getT());
}

}


泛型使得代码更简便安全。

2)泛型方法

package javazongjie;

public class GenericMethod {

public <K,V> void f(K k,V v) {
System.out.println(k.getClass().getSimpleName());
System.out.println(v.getClass().getSimpleName());
}

public static void main(String[] args) {
GenericMethod genericMethod = new GenericMethod();
genericMethod.f(new Integer(1), new String("abc"));
//>>Integer
//>>String
}

}


3 类型擦除

1)什么是类型擦除

类型参数只存在于编译期,在运行时,Java的虚拟机(JVM)并不知道泛型的存在。

package javazongjie;

import java.util.ArrayList;

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);
//>>true
//在JVM看来它们是同一个类
}
}


2) 擦除带来的问题

package javazongjie;

public class HasF {

public void f() {
System.out.println("HasF.f()");
}
}


package javazongjie;

public class Manipulator<T> {

private T obj;

public Manipulator(T obj) {
super();
this.obj = obj;
}

public void manipulate() {
obj.f();
//编译出错
}
}


解决办法:

加上一个边界

package javazongjie;

public class Manipulator<T extends HasF> {

private T obj;

public Manipulator(T obj) {
super();
this.obj = obj;
}

public void manipulate() {
obj.f();
}
}


3)类型擦除的补偿

任何在运行期需要知道确认类型的代码都无法工作。

4 泛型数组

1)如何创建泛型数组

package javazongjie;

public class ArrayOfGeneric {

static final int SIZE = 100;
static Holder<Integer>[] holder;
public static void main(String[] args) {
//holder = new Holder<Integer>[SIZE];//编译错误

holder = (Holder<Integer>[])new Holder[SIZE];
System.out.println(holder.getClass().getName()); //输出[Ljavazongjie.Holder;
//成功创建泛型数组的唯一方式是创建一个类型擦除的数组,然后转型

holder[0] = new Holder<Integer>(1);
}

}


2)使用 T[] array

package javazongjie;

public class GenericArray<T extends Integer> {

private T[] array;
@SuppressWarnings("unchecked")
public GenericArray(int sz) {
array = (T[])new Integer[sz];
}
public void put(int index, T item) {
array[index] = item;
}
public T get(int index) {
return array[index];
}

public T[] rep() {
return array;
}

public static void main(String[] args) {
GenericArray<Integer> gai =
new GenericArray<Integer>(10);
gai.put(0, 100);
System.out.println(gai.get(0));
}
}


3 使用反射

package javazongjie;

import java.lang.reflect.Array;

public class GenericArrayWithTypeToken<T> {

private T[] array;

public GenericArrayWithTypeToken(Class<T> type, int sz) {
array = (T[])Array.newInstance(type, sz);
}

public void put(int index, T item) {
array[index] = item;
}

public T get(int index) { return array[index]; }

public T[] rep() { return array; }

public static void main(String[] args) {
GenericArrayWithTypeToken<Integer> gai =
new GenericArrayWithTypeToken<Integer>(
Integer.class, 10);
Integer[] ia = gai.rep();
System.out.println(ia);
}
}


5 数组的协变

class Fruit {}
class Apple extends Fruit {}
class Jonathan extends Apple {}
class Orange extends Fruit {}

public class CovariantArrays {
public static void main(String[] args) {
Fruit[] fruit = new Apple[10];
fruit[0] = new Apple(); // OK
fruit[1] = new Jonathan(); // OK
// Runtime type is Apple[], not Fruit[] or Orange[]:
try {
// Compiler allows you to add Fruit:
fruit[0] = new Fruit(); // ArrayStoreException
} catch(Exception e) { System.out.println(e); }
try {
// Compiler allows you to add Oranges:
fruit[0] = new Orange(); // ArrayStoreException
} catch(Exception e) { System.out.println(e); }
}
} /* Output:
java.lang.ArrayStoreException: Fruit
java.lang.ArrayStoreException: Orange
*///:~


6 使用通配符

1)上边界限定通配符

<? extends Fruit>


2)下边界限定通配符

? super T
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: