泛型类型信息被擦除
public class Erased<T> {
private final int SIZE = 100;
public static void f(Object arg){
// if(arg instanceof T) //error
// T[] array = new T[SIZE]; //error
}
}
1.类型信息被擦除 不可进行实例类型的判断
2.类型信息被擦除 不可实例该种类型的数组
可以通过间接的方式获得当前实例类型
class Building{}
class House extends Building{}
public class ClassTypeCapture<T> {
Class<T> kind;
public ClassTypeCapture(Class<T> kind) {
this.kind = kind;
}
public boolean Instanceof(Object obj){
return kind.isInstance(obj); //判断是否为当前类的实例
}
public static void main(String []argv){
ClassTypeCapture<Building> ctc = new ClassTypeCapture<Building>(Building.class);
System.out.println(ctc.Instanceof(new House()));
}
}
同在该方式来判断当前的实例类型 通过 Class.IsInstance判断类型
泛型创建对象
class ClassAsFactory<T>{
private T x;
public ClassAsFactory(Class<T> kind) {
try {
x = kind.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
class Employee{}
public class InstantiateCenericType {
public static void main(String []args){
ClassAsFactory<Employee> ecf = new ClassAsFactory<>(Employee.class); //OK
System.out.println("ClassFactory create success!");
try{
ClassAsFactory<Integer> ecf1 = new ClassAsFactory<Integer>(Integer.class); //error
}catch (Exception e){
e.printStackTrace();
}
}
}
** 使用这种方式虽然可以创建对象但是不符合规范,逻辑不够优雅 (SUN公司不推荐)**
优雅方式一
interface FactoryI<T>{
T create();
}
class Foo2<T>{
private T x;
public <F extends FactoryI<T>> Foo2(F factory){
x = factory.create();
}
}
class IntegerFactory implements FactoryI<Integer>{
@Override
public Integer create() {
return new Integer(0);
}
}
class Widget{
public static class Factory implements FactoryI<Widget>{
@Override
public Widget create() {
return new Widget();
}
}
}
public class FactoryConsraint {
public static void main(String [] argv){
new Foo2<Integer>(new IntegerFactory());
new Foo2<Widget>(new Widget.Factory());
}
}
优雅方式二
abstract class GenericWithCreate<T>{
final T element;
public GenericWithCreate(){ element = create(); } //第二步
abstract T create();
}
class X{}
class Creator extends GenericWithCreate<X>{
@Override
X create() { //第三步
return new X();
}
public void f(){ //第四步
System.out.println(element.getClass().getSimpleName());
}
}
public class CreateGeneric {
public static void main(String []argc){
Creator c = new Creator(); //第一步
c.f(); //第五步
}
}
创建泛型数组
创建数组最菜的方式
import java.util.ArrayList;
import java.util.List;
public class ListOfGenerics<T> {
private List<T> array = new ArrayList<>();
public void add(T item){array.add(item);}
public T get(int index){return array.get(index);}
}
创建指针数组
public class ArrayOfGeneric {
static final int SIZE = 100;
static Generic<Integer>[] gia;
public static void main(String [] argv){
// 产生运行错误
// gia = (Generic<Integer>[]) new Object[SIZE];
gia = new Generic[SIZE];
System.out.println(gia.getClass().getSimpleName());
gia[0] = new Generic<Integer>();
}
}
** 实例擦除类型信息的类型指针数组 再将实时的变量的引用添加进数组之中**
菜菜方法二
public class GenericArray<T> {
private T[] array;
public GenericArray(int sz) {
array = (T[]) new Object[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 [] argv){
GenericArray<Integer> gai = new GenericArray<Integer>(10);
Object [] a = gai.rep();
//Integer[] b = gai.rep(); //error 不是继承类 无法实现转换
}
}
菜菜方式三
public class GenericArray2<T> {
private Object[] array;
public GenericArray2(int sz) {
array = new Object[sz];
}
public void put(int index, T item){
array[index] = item;
}
public T get(int index){
return (T)array[index];
}
public T[] rep(){
return (T[]) array;
}
public static void main(String [] argv){
GenericArray2<Integer> gai = new GenericArray2<Integer>(10);
Object [] a = gai.rep();
for (int i = 0; i< 10; i++){ gai.put(i, i); }
for (int i = 0; i< 10; i++){
Integer j;
j = gai.get(i);
System.out.printf(" " + j);
}
// Integer[] b = gai.rep(); // error 但是此处依旧不可 无可推翻底层的数组类型
}
}
**无法直接推翻底层的数组类型 转换思路: 通过反射从底层直接构建 **
这个稍稍好一点
import java.lang.reflect.Array;
public class GenericArrayWithTypeToken<T> {
private T[] array;
public GenericArrayWithTypeToken(Class<T> type, int size) {
array= (T[]) Array.newInstance(type, size);
}
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 [] argv){
GenericArrayWithTypeToken<Integer> gai = new GenericArrayWithTypeToken<Integer>(Integer.class,10);
Object [] a = gai.rep();
for (int i = 0; i< 10; i++){ gai.put(i, i); }
for (int i = 0; i< 10; i++){
Integer j;
j = gai.get(i);
System.out.printf(" " + j);
}
Integer[] b = gai.rep();
for(int i : b){
System.out.printf(" " + i);
}
}
}