精华内容
下载资源
问答
  • Java 的泛型

    2013-01-07 14:26:21
    Java 泛型的参数只可以代表类,不能代表个别对象。 由于 Java 泛型的类型参数之实际类型在编译时会被消除,所以无法在运行时得知其类型参数类型。 Java 编译器在编译泛型时会自动加入类型转换编码,故运行速度...

    Java 泛型的参数只可以代表类,不能代表个别对象。

    由于 Java 泛型的类型参数之实际类型在编译时会被消除,所以无法在运行时得知其类型参数的类型。

    Java 编译器在编译泛型时会自动加入类型转换的编码,故运行速度不会因为使用泛型而加快。

    Java 允许对个别泛型的类型参数进行约束,包括以下两种形式(假设 T 是泛型的类型参数,C 是一般类、泛类,或是泛型的类型参数):T 实现接口 I 。T 是 C ,或继承自 C 。一个泛型类不能实现Throwable接口。  

    展开全文
  • 深入理解java的泛型

    千次阅读 2020-05-07 07:31:51
    深入理解java的泛型 简介 泛型是JDK 5引入的概念,泛型的引入主要是为了保证java中类型的安全性,有点像C++中的模板。 但是Java为了保证向下兼容性,它的泛型全部都是在编译期间实现的。编译器执行类型检查和类型...

    简介

    泛型是JDK 5引入的概念,泛型的引入主要是为了保证java中类型的安全性,有点像C++中的模板。

    但是Java为了保证向下兼容性,它的泛型全部都是在编译期间实现的。编译器执行类型检查和类型推断,然后生成普通的非泛型的字节码。这种就叫做类型擦除。编译器在编译的过程中执行类型检查来保证类型安全,但是在随后的字节码生成之前将其擦除。

    这样就会带来让人困惑的结果。本文将会详细讲解泛型在java中的使用,以避免进入误区。

    泛型和协变

    有关协变和逆变的详细说明可以参考:

    深入理解协变和逆变

    这里我再总结一下,协变和逆变只有在类型声明中的类型参数里才有意义,对参数化的方法没有意义,因为该标记影响的是子类继承行为,而方法没有子类。

    当然java中没有显示的表示参数类型是协变还是逆变。

    协变意思是如果有两个类 A<T> 和 A<C>, 其中C是T的子类,那么我们可以用A<C>来替代A<T>。

    逆变就是相反的关系。

    Java中数组就是协变的,比如Integer是Number的子类,那么Integer[]也是 Number[]的子类,我们可以在需要 Number[] 的时候传入 Integer[]。

    接下来我们考虑泛型的情况,List<Number> 是不是 List<Integer>的父类呢?很遗憾,并不是。

    我们得出这样一个结论:泛型不是协变的。

    为什么呢?我们举个例子:

    List<Integer> integerList = new ArrayList<>();
            List<Number> numberList = integerList; // compile error
            numberList.add(new Float(1.111));
    

    假如integerList可以赋值给numberList,那么numberList可以添加任意Number类型,比如Float,这样就违背了泛型的初衷,向Integer list中添加了Float。所以上面的操作是不被允许的。

    刚刚我们讲到Array是协变的,如果在Array中带入泛型,则会发生编译错误。比如new List<String>[10]是不合法的,但是 new List<?>[10]是可以的。因为在泛型中?表示的是未知类型。

    
    List<?>[] list1 = new List<?>[10];
    
    List<String>[] list2 = new List<String>[10]; //compile error
    

    泛型在使用中会遇到的问题

    因为类型擦除的原因,List<String>和List<Integer>在运行是都会被当做成为List。所以我们在使用泛型时候的一些操作会遇到问题。

    假如我们有一个泛型的类,类中有一个方法,方法的参数是泛型,我们想在这个方法中对泛型参数进行一个拷贝操作。

    public class CustUser<T> {
    
        public void useT(T param){
            T copy = new T(param);  // compile error
        }
    }
    

    上面操作会编译失败,因为我们并不知道T是什么,也不知道T到底有没有相应的构造函数。

    直接clone T是没有办法了,如果我们想copy一个Set,set中的类型是未定义的该怎么做呢?

        public void useTSet(Set<?> set){
            Set<?> copy1 = new HashSet<?>(set);  // compile error
            Set<?> copy2 = new HashSet<>(set);
            Set<?> copy3 = new HashSet<Object>(set);  
        }
    

    可以看到?是不能直接用于实例化的。但是我们可以用下面的两种方式代替。

    再看看Array的使用:

        public void useArray(){
             T[] typeArray1= new T[20];  //compile error
            T[] typeArray2=(T[]) new Object[20];
            T[] typeArray3 = (T[]) Array.newInstance(String.class, 20);
        }
    

    同样的,T是不能直接用于实例化的,但是我们可以用下面两种方式代替。

    类型擦除要注意的事项

    因为类型擦除的原因,我们在接口实现中,实现同一个接口的两个不同类型是无意义的:

    public class someClass implements Comparable<Number>, Comparable<String> { ... } // no
    

    因为在编译过后的字节码看来,两个Comparable是一样的。

    同样的,我们使用T来做类型强制转换也是没有意义的:

    public <T> T cast(T t, Object o) { return (T) o; }
    

    因为编译器并不知道这个强制转换是对还是错。

    总结

    本文讨论了泛型在java中使用中可能会存在的问题,希望大家能够喜欢。

    本文的例子https://github.com/ddean2009/learn-java-collections

    更多精彩内容且看:

    本文作者:flydean程序那些事

    本文链接:http://www.flydean.com/java-generics-in-deep/

    本文来源:flydean的博客

    欢迎关注我的公众号:程序那些事,更多精彩等着您!

    展开全文
  • Java 的泛型擦除和运行时泛型信息获取 Java 的泛型擦除 擦除 Class c1 = new ArrayList<Integer>().getClass(); Class c2 = new ArrayList<String>().getClass(); System.out.println(c1 == c2); /...

    Java 的泛型擦除和泛型信息获取

    Java 的泛型擦除

    擦除

    Class c1 = new ArrayList<Integer>().getClass();  
    Class c2 = new ArrayList<String>().getClass();   
    System.out.println(c1 == c2);  
      
    /* Output 
    true 
    */  
    

    ArrayList<Integer> 和 ArrayList<String> 在编译的时候是完全不同的类型。你无法在写代码时,把一个 String 类型的实例加到 ArrayList<Integer> 中。但是在程序运行时,的的确确会输出true。
    这就是 Java 泛型的类型擦除造成的,因为不管是 ArrayList<Integer> 还是 ArrayList<String>,在编译时都会被编译器擦除成了 ArrayList。Java 之所以要避免在创建泛型实例时而创建新的类,从而避免运行时的过度消耗。

    List<Integer> list = new ArrayList<Integer>();  
    Map<Integer, String> map = new HashMap<Integer, String>();  
    System.out.println(Arrays.toString(list.getClass().getTypeParameters()));  
    System.out.println(Arrays.toString(map.getClass().getTypeParameters()));  
      
    /* Output 
    [E] 
    [K, V] 
    */  
    

    我们可能期望能够获得真实的泛型参数,但是仅仅获得了声明时泛型参数占位符。getTypeParameters 方法的 Javadoc 也是这么解释的:仅返回声明时的泛型参数。所以,通过 getTypeParamters 方法无法获得运行时的泛型信息。

    擦除到上限

    class A<T extends Number> {
    }
    

    再用 javap -v cc.unmi.A 来看泛型签名
    Signature: #18 // <T:Ljava/lang/Number;>Ljava/lang/Object;

    转换

    本来a是带有泛型信息,但是b没有,所以在赋值过程中泛型信息就丢失了,b中的T的类型会变成其上限Number

    //一下代码中,当把一个带泛型信息的a的实例赋值给一个不带泛型信息的的b的时候,
    //a中所有的泛型信息都会发生丢失,也就是说T是Integer的这一信息会丢失,b只知道
    //T的类型是Number而已
    package ErasureAndConversion;
     
     
    import UseIt.A1;
     
    class Apple<T extends  Number>{
        T size;
        public Apple(){
     
        }
        public Apple(T size){
            this.size = size;
        }
        public void setSize(T size){
            this.size = size;
        }
        public T getSize(){
            return this.size;
        }
    }
     
     
    public class Erasure {
        public static void main(String args[]){
            Apple<Integer> a = new Apple<>(6);
    //        a指向的实例是带有泛型信息的
     
            Integer as = a.getSize();
    //        实例a中的T是Integer类型的,所以赋值给as没有任何问题
            Apple b  = a;
    //        这一句就是说明问题的关键了,b是不带泛型信息的,所以a中的泛型信息
    //        也就会被擦除,所以,a中的T的类型就只是Number而已了
     
            Number size1 = b.getSize();
    //        b中的T类型是Number,所以赋值给Number类型的值没有任何问题
     
     
    //        Integer size2 = b.getSize();
    //        但是,b中的T并不是Integer的了,因为泛型信息已经被擦除了,所以这一句会
    //        报错。
            Integer size3 = a.getSize();
    //       最后这一句并不会报错,b会发生泛型信息丢失但是a并不会受影响
        }
    }
    

    下面这两个例子说明的是一样的问题,或者说第二个例子是第一个例子的直观表现,说的是当把带有泛型信息的集合赋值给没有泛型信息的集合时泛型信息就丢失了,所以在把list赋值给ls的时候不会发生问题,因为list已经不知道具体的泛型信息是什么了,所以是Object,所以可以赋值给ls,但是一旦要访问集合中的元素的时候,就会发生类型不匹配的问题。

    //java允许把一个List赋值给一个List<Type>所以在下面 List<String> ls = list;
    //这一句仅仅只会发生警告而已。
    package ErasureAndConversion;
     
    import java.util.ArrayList;
    import java.util.List;
     
    public class Erasure2 {
        public static void main(String args[]){
            List<Integer> li = new ArrayList<>();
            li.add(6);
            li.add(5);
            List list = li;
            List<String> ls = list;
    //        一样的道理,List没有泛型信息,所以li的泛型信息就丢失了,所以赋值给ls
    //        是没有问题的
     
    //        System.out.println(ls.get(0));
    //        但是当访问ls中的元素的时候,就会发生类型不匹配的问题
        }
    }
    
    //这个例子和上面的例子是一模一样的
    package ErasureAndConversion;
     
    import java.util.ArrayList;
    import java.util.List;
     
    public class Erasure3 {
        public static void main(String args[]){
            List list = new ArrayList();
            ((ArrayList) list).add(5);
            ((ArrayList) list).add(4);
    //        System.out.println((String)list.get(0));
        }
    }
    

    泛型信息的获取

    继承一个泛型基类

    class A<T, ID> {  
    }  
      
    class B extends A<String, Integer> {  
    }  
      
    public class Generic {  
        public static void main(String[] args) {  
            ParameterizedType parameterizedType = (ParameterizedType) B.class.getGenericSuperclass();  
            
    		Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();  
    		for(Type actualTypeArgument: actualTypeArguments) {  
    		    System.out.println(actualTypeArgument);  
    		}  
    		
    		Class clazz = (Class) parameterizedType.getActualTypeArguments()[0];
            System.out.println(clazz);
        }  
    }  
    

    上面的代码输出:
    class java.lang.String
    class java.lang.Integer
    class java.lang.String

    实现一个泛型接口

    interface A<T, ID> {  
    }  
      
    class B implements A<String, Integer> {  
    }  
    
    public class Generic {  
        public static void main(String[] args) {  
            ParameterizedType parameterizedType = (ParameterizedType) B.class.getGenericInterfaces();  
            
    		Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();  
    		for (Type actualTypeArgument : actualTypeArguments) {  
    		    System.out.println(actualTypeArgument);  
    		}  
    		
    		Class clazz = (Class) parameterizedType.getActualTypeArguments()[0];
            System.out.println(clazz);
        }  
    }
    

    同样能得到上面的一样的结果。

    运行时泛型信息的获取 (假象,实质是通过定义类的方式)

    引入一点小知识
    匿名内部类
    概念:即内部类的简化写法
    前提:存在一个类(可以是具体类也可以是抽象类)或接口
    格式:new 类名或接口名{重写的方法}
    本质:创建的是继承了类或实现了接口的子类匿名对象
    匿名类的声明:
    匿名类的声明是由java编译器自动派生自一个类实例创建表达式;
    匿名类永远不能是抽象的;
    匿名类总是隐式的final;
    匿名类总是一个内部类,并且不能是static的;

    由于Java泛型的实现机制,使用了泛型的代码在运行期间相关的泛型参数的类型会被擦除,我们无法在运行期间获知泛型参数的具体类型(所有的泛型类型在运行时都是Object类型),但是在编译java源代码成 class文件中还是保存了泛型相关的信息,,这些信息被保存在class字节码常量池中,使用了泛型的代码处会生成一个signature签名字段,通过签名signature字段指明这个常量池的地址。

    Java 引入泛型擦除的原因是避免因为引入泛型而导致运行时创建不必要的类。通过前面的知识我们其实就可以通过定义类的方式,在类信息中保留泛型信息,从而获得这些泛型信息。简而言之,Java 的泛型擦除是有范围的,即类定义中的泛型是不会被擦除的。

    有些场景中,我们需要获取泛型信息的。比如,在调用 HTTP 或 RPC 接口时,我们需要进行序列化和反序列的工作。
    例如,我们通过一个 HTTP 接口接收如下的 JSON 数据

    [{  
        "name": "Stark",  
        "nickName": "Iron Man"  
    },  
    {  
        "name": "Rogers",  
        "nickName": "Captain America"  
    }]  
    

    我们需要将其映射为 List<Avenger>。

    但是之前我们提到了泛型擦除,那我们所使用的 HTTP 或 RPC 框架是如何获取 List 中的泛型信息呢?

    如下代码

    Map<String, Integer> map = new HashMap<String, Integer>() {};  
    Type type = map.getClass().getGenericSuperclass();  
    ParameterizedType parameterizedType = ParameterizedType.class.cast(type);  
    //ParameterizedType parameterizedType = (ParameterizedType)map.getClass().getGenericSuperclass();
    for (Type typeArgument : parameterizedType.getActualTypeArguments()) {  
        System.out.println(typeArgument.getTypeName());  
    }  
      
    /* Output 
    java.lang.String 
    java.lang.Integer 
    */  
    

    上面这段代码展示了如何获取 map 这个实例所对应类的泛型信息。显然,这次我们成功获得了其中泛型参数信息。有了这些泛型参数,上面所提到的序列化和反序列化工作就是可能的了。

    那为什么之前不可以,而这次可以了呢?请注意一个细节

    前面的变量声明

    Map<Integer, String> map = new HashMap<Integer, String>();  
    

    本节中的变量声明

    Map<String, Integer> map = new HashMap<String, Integer>() {};  
    

    其中最关键的差别是本节的变量声明多了一对大括号,其实是创建了一个匿名内部类,这个类是 HashMap 的子类,泛型参数限定为了 String 和 Integer,这样就通过定义类的方式保留了泛型信息。

    框架中的应用

    其实很多框架就是使用类定义中的泛型不会被擦除这个特性,实现了相应的功能。

    例如,SpringWeb模块的RestTemplate 和 alibaba的fastJson,我们可以使用如下写法:

    //这里的ParameterizedTypeReference是一个抽象类,因此约束了必须创建ParameterizedTypeReference的子类,由此成功获取到泛型的实际类型
    ResponseEntity<ResponseDTO<UserKeyDTO>> result = restTemplate.exchange(url, null, new ParameterizedTypeReference<ResponseDTO<UserKeyDTO>>(){});
    
    //通过创建TypeReference的匿名内部类的方式来保留反省信息,以便json反序列化时能反射获取到泛型实际类型
    ResponseDTO<SysCryptDTO> responseDTO = JSONObject.parseObject(jsonString, new TypeReference<ResponseDTO<SysCryptDTO>>() {});
    

    其中的 new ParameterizedTypeReference<YourType>() {} 就是通过定义一个匿名内部类的方式来获得泛型信息,从而进行反序列化的工作。

    总结

    Java 泛型擦除是 Java 泛型中的一个重要特性,其目的是避免过多的创建类而造成的运行时的过度消耗。所以,想 ArrayList<Integer> 和 ArrayList<String> 这两个实例,其类实例是同一个。

    但很多情况下我们又需要在运行时获得泛型信息,那我们可以通过定义类的方式(通常为匿名内部类,因为我们创建这个类只是为了获得泛型信息)在运行时获得泛型参数,从而满足例如序列化、反序列化等工作的需要。

    只要理解了 Java 引入泛型擦除的原因,也自然能理解如何在运行时获取泛型信息了。

    展开全文
  • c++的泛型编程和容器是通过stl实现的,请问java的泛型是如何实现的
  • 为什么说Java的泛型是“假泛型”?

    千次阅读 2018-10-20 11:29:39
    Java的泛型是JDK5带来的新特性,它有如下的优点: 适用于多种数据类型执行相同的代码 泛型中的类型在使用时指定 泛型归根到底就是“模版” 但是,为了做到向下兼容,Java中的泛型仅仅是一个语法糖,并不是C++那样的...

    个人博客:https://blog.N0tExpectErr0r.cn

    小专栏:https://xiaozhuanlan.com/N0tExpectErr0r

    Java泛型

    Java的泛型是JDK5带来的新特性,它有如下的优点:

    • 适用于多种数据类型执行相同的代码
    • 泛型中的类型在使用时指定
    • 泛型归根到底就是“模版”

    但是,为了做到向下兼容,Java中的泛型仅仅是一个语法糖,并不是C++那样的真泛型。

    如何证明呢?我们可以看看下面的例子

    证明

    在这个例子中,我们定义了一个List<Integer>集合,我们可以调用add方法向其中加入Integer类型的值。

    如果我们像下面一样调用add方法向里面加入String,当然会报错:

    public static void main(String[] args) throws Exception {
    	List<Integer> list = new ArrayList<>();
        list.add("str");
    }
    

    错误信息如下:

    add (java.lang.Integer) in List cannot be applied to (java.lang.String)

    显然,我们是没法直接向其中加入String类型的值的。

    不过,我们可以另辟蹊径。我们尝试通过反射,间接地调用add方法,向这个List<Integer>中加入String类型的值。

    public static void main(String[] args) throws Exception {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        Method add = list.getClass().getMethod("add", Object.class);
        add.invoke(list,"str");
        System.out.println(list);
        System.out.println(list.get(1));
    }
    

    运行发现,并没有报错,而且我们成功地打印了这个str!

    [1, str]
    str

    由此可见,所谓的泛型确实是假泛型。原本只能装入Integer的List中,我们成功装入了一个String类型的值。

    类型擦除

    实际上,Java 的泛型仅仅在编译期有效,在运行期则会被擦除,也就是说所有的泛型参数类型在编译后都会被清除掉。这就是所谓的类型擦除

    我们看到下面的例子:

    public class Test {  
        public void addList(List<String> stringList){
        }  
        public void addList(List<Integer> intList) {
        }  
    }  
    

    我们在这个类中定义了两个方法,传入List<String>List<Integer>这两个不同类型的参数,看起来并没有什么问题。

    可是,编译器却报出如下的错误:

    Method addList(List) has the same erasure addList(List) as another method in type Test

    也就是说,这两个方法的签名在进行了类型擦除后均为addList(List<E>)

    下面是关于List的类型擦除的一些情况:

    • List<String>List<T>擦除后的类型为List
    • List<String>[]List<T>[] 擦除后的类型为 List[]
    • List<? extends E>List<? super E>擦除后的类型为List<E>
    • List<T extends Serialzable & Cloneable>擦除后类型为 List<Serializable>

    C++模板

    C++的模板就是我们所谓的"真泛型",下面是一段C++使用模板的类的示例:

    #include<iostream>
    using namespace std;
    
    template<class T> class Test
    {
    	private:
    		T obj;
    	public:
    	  	Test(T x){obj=x;}
    	  	void try(){obj.fun();}
    };
    
    class A
    {
    	public:
    	  	void fun(){cout<<"A::fun()"<<endl;}
    };
    
    int main(int argc, char* argv[]){
    	A a;
    	Test<A> test(a);
    	test.try();
    }
    

    在类Test中存储了类型为T的对象。很有趣的一点是我们在Test::try()方法中调用了objfun()方法。它怎么知道fun()方法是T所包含的呢?

    在我们调用Test的构造函数实例化这个模板时,编译器进行了检查,发现A类确实含有fun方法,因此编译可以通过。

    如果A类并不含有fun方法,则编译不会通过。这样类型安全就得到了保障。

    在 C++ 模板中,编译器使用提供的类型参数来扩充模板,因此为List<A>生成的 C++ 代码不同于为 List<B>生成的代码,List<A>List<B> 实际上是两个不同的类。

    总结

    虽然java中的泛型是“假”的,会有类型擦除的操作。但是不可否认,泛型的引入对Java语言影响仍然是非常大的。

    因此在我们使用泛型的时候,应当尽量考虑到类型擦除这个特点,多考虑一下自己的封装是否类型安全。

    展开全文
  • 问一道Java的泛型题目

    2019-03-20 19:43:21
    问一道Java的泛型题目 下面的代码定义了一个媒体(Media)接口及其三个子接口:图书(Book),视频(Video)和报纸(Newspaper),library类是一个非泛型类,请用泛型重新设计改类 import java.util.List; import ...
  • 浅谈java的泛型

    2015-01-19 16:13:19
     java泛型,就是java语言发展到一定的程度后,为了实现某些功能而发展出来的技术,但需要指出来的是,java的泛型和C++的泛型是有一定的区别的,java中只能做到形似而神不似的阶段,比如他不能对两个泛型进行运算,...
  • 前言 Java高级技术系列前言... Java的泛型 泛型边界,参见下面的代码: public class Main { public static void main(String[] args) { FX ex_num = new FX(100); FX ex_int = new FX(200); FX ex_str = n
  • Java的泛型封装方式

    千次阅读 2017-03-14 17:37:01
    Java的泛型封装方式package base;import java.util.List;public interface DaoSupport<T> { /** * 保存实体 * * @param entity */ void save(T entity); /** * 删除实体 * * @param
  • Java的泛型声明使用

    千次阅读 2016-09-27 17:08:31
    泛型一直在使用,没做个小结,今天简单介绍下首先java的泛型是个伪泛型,它就是个java中类型的参数化(可以理解为java类型的一个符号),只在编译阶段存在,作用是类型的检查,防止运行时抛出异常。泛型的声明:是在...
  • Java 的泛型擦除 代码一 Class c1 = new ArrayList().getClass(); Class c2 = new ArrayList().getClass(); System.out.println(c1 == c2); /* Output true */ ArrayList 和 ArrayList 在编译的时候是完全不同...
  • java的泛型的特点

    千次阅读 2016-09-14 09:12:42
    java中的泛型只是在程序源码中存在,在编译后的字节码文件中,就已经替换为原来的原生类型(Raw Type,...泛型技术实际上是Java的一颗语法糖,Java语言的泛型实际方法称为类型擦除,基于这种方法实现的泛型称为伪泛型。
  • 总结一下Java的泛型编程和c++模板的区别和联系。 泛型本质上是提供类型的"类型参数",它们也被称为参数化类型(parameterized type)或参量多态(parametric polymorphism)。其实泛型思想并不是 Java 最先引入的...
  • java的泛型原理

    2016-05-28 20:57:38
    java中,有一种很特殊类型,叫泛型。它一般是在类或接口后面加上一对,里面通过一个大写英文字母来表示该类或接口实现了泛型,其实严格来说泛型是一种类型是不正确,下面简单说说泛型的原理。  java泛型...
  • Java的泛型及实现

    2018-09-06 11:36:30
    1.1、c++模板和java泛型的异同 1.2、java泛型的好处 2、类型擦除 3、泛型的实现原理 3.1、保证类型安全 3.2、实现自动类型转换 4、泛型继承关系 5、泛型使用中注意点 5.1、运行时类型查询 5.2、异常...
  •   在 Java 的泛型类型中使用通配符  ...我们知道,Java 的泛型类型如同 java.lang.String,java.io.File 一样,属于普通的 Java 类型。比方说,下面两个变量的类型就是互不相同的:  Li
  • java 的泛型 T

    2014-11-04 14:57:28
    加入有人问你 java 中的泛型 T 代表什么意思?泛型是java的基本数据类型还是对象类型呢?你怎么回答呢? 我们平时接触最多的 泛型 莫非 List,他可以放任何东西,这似乎很平常的,ActionFragment 这种是什么意思呢?...
  • 如何理解Java的泛型

    2017-09-18 22:16:52
    在javaSE1.5版本之前是没有java泛型的,这个时候程序员是通过,对类型Object引用,来实现参数任意化。泛型是javaSE1.5新特性。泛型的本质是参数化类型,它和Object功能,都是实现参数任意化,但是泛型,能够...
  • Java的泛型(参数化类型)

    万次阅读 多人点赞 2018-05-30 20:09:54
    泛型的本质是为了参数化类型(在不创建新类型情况下,通过泛型指定不同类型来控制形参具体限制类型)。也就是说在泛型使用过程中,操作数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,...
  • java的泛型数组

    2015-12-31 23:56:44
    有了泛型之后,运行时就不会报ClassCastException错误。
  • Java的泛型是什么?为什么要用它?

    千次阅读 多人点赞 2020-07-27 19:51:57
    本文讲解的是Java语言中的泛型。泛型顾名思义就是广泛的数据类型,也就是说什么数据类型都可以。本文从ArrayList说起,讲解Java的泛型类、泛型接口和泛型方法的使用。
  • 关于Java的泛型方法

    2015-03-14 20:09:27
    文章参考自:... 有泛型方法还有泛型类。 类似于如下代码定义的泛型是泛型方法 : package com.test.GenericTest; import java.util.ArrayList; import java.util.List;

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 38,439
精华内容 15,375
关键字:

java的泛型

java 订阅