当前位置:首页 > 开发 > 编程语言 > Java > 正文

【Java范型七】范型消除

发表于: 2014-09-01   作者:bit1129   来源:转载   浏览:
摘要: 范型是Java1.5引入的语言特性,它是编译时的一个语法现象,也就是说,对于一个类,不管是范型类还是非范型类,编译得到的字节码是一样的,差别仅在于通过范型这种语法来进行编译时的类型检查,在运行时是没有范型或者类型参数这个说法的。 范型跟反射刚好相反,反射是一种运行时行为,所以编译时不能访问的变量或者方法(比如private),在运行时通过反射是可以访问的,也就是说,可见性也是一种编译时的行为,在

范型是Java1.5引入的语言特性,它是编译时的一个语法现象,也就是说,对于一个类,不管是范型类还是非范型类,编译得到的字节码是一样的,差别仅在于通过范型这种语法来进行编译时的类型检查,在运行时是没有范型或者类型参数这个说法的。

范型跟反射刚好相反,反射是一种运行时行为,所以编译时不能访问的变量或者方法(比如private),在运行时通过反射是可以访问的,也就是说,可见性也是一种编译时的行为,在运行时,JVM中的字节码对彼此都是可见的。

 

Java在将源代码编译后,自动去除了关于范型的信息,范型是编译时的语法现象,这给范型的处理带来一些很不直观的结果。

 

 范型类不能用于instanceof判断

 

package com.tom.lang.generics;


public class Generics<T> {
    public static void main(String[] args) {
        Generics<String> stringGenerics =new Generics<String>();
        if (stringGenerics instanceof Generics<String>) {//编译错, 范型类不能用于instanceof运算符
            
        }
        
    }
}

 

 范型参数不能作为方法签名的一部分信息

package com.tom.lang.generics;


public class Generics<T> {
    public void method(Generics<String> obj) { //编译错,两个method冲突

    }

    public void method(Generics<Integer> obj) {

    }
}

 

范型类不能获得Class对象

 

Data<Integer>.class //范型类加.class来获得它的class对象

 

 

范型处理困难

Gson这个GSON算是比较优雅的解决了范型的问题,但是范型的运行时消除这个特性还是给使用Gson带来一些额外的代码,比如如下的代码不用任何额外处理时

 

 

package com.tom.lang.generics;

import com.google.gson.Gson;

class Point {
    private int x;
    private int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}

class Data<T> {
    private T data;

    public Data(T data) {
        this.data = data;
    }
    public T getData() {
        return data;
    }
}

public class DataTest {
    public static void main(String[] args) {
        Data<Point> d = new Data<Point>(new Point(100,200));
        String str = new Gson().toJson(d);
        System.out.println(str);
        Data<Point> dd = new Gson().fromJson(str, Data.class);
        //虽然dd看上去像是一个带有参数类型为Point的Data范型类变量,实际上运行时得到的结果是,Data含有一个data字段,但是这个字段
        //是TreeMap类型的,由于运行的范型消除,所以,即使返回的dd中的data字段是Map类型,仍然不会报错!
        //Point p = dd.getData(); //运行时,类型转换失败
        Map map = dd.getData(); //成功
    }
}


 

 上面的正确做法

 

 

package com.tom.lang.generics;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;

class Point {
    private int x;
    private int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}

class Data<T> {
    private T data;

    public Data(T data) {
        this.data = data;
    }
    public T getData() {
        return data;
    }
}

public class DataTest {
    public static void main(String[] args) {
        Data<Point> d = new Data<Point>(new Point(100,200));
        String str = new Gson().toJson(d);
        System.out.println(str);
        Type type = new TypeToken<Data<Point>>(){}.getType();//将范型类型包装到TypeToken中保存
        Data<Point> dd = new Gson().fromJson(str, type); //转型正确
        Point p = dd.getData();//可以正确取值
    }
}


 

 

 

 

 

 

【Java范型七】范型消除

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
原文地址:http://blog.csdn.net/m13666368773/article/details/7951223 Java的泛型在代码中引用时
任何一个想在程序开发这条路上走远点的人都应当多了解几门语言,多接触一些编程泛型,才能打开眼界
七周七语言:理解多种编程范型 编辑推荐   2011年Jolt大奖图书   带你轻松入门七种先锋语言  
偶然间,发现IronPython 1.0支持.Net的范型类,可以讲太强大了。哈! 用以下代码可以测试出来: fro
本文例子下载 http://files.cnblogs.com/foundation/GenericActivitySample.rar 范型Activity Activ
  我认为,图书的封面很重要,因为首先映入读者眼帘的就是封面,他可以诱发潜在的读者去注意图书,
七周七语言:理解多种编程范型(2011年Jolt大奖图书) 编辑推荐   2011年Jolt大奖图书   带你轻松
说明:在List<T>范型集合中提供了一类委托,以确定要寻找集合中的哪些符合条件的单个元素或者
  现在我们所做的很大一部分工作其实就是CRUD, 我们的aspx.cs页面充斥着大量的CRUD逻辑.当需要
说明:在List<T>范型集合中提供了一类委托,以确定要寻找集合中的哪些符合条件的单个元素或者
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号