java的泛型与反射机制

Posted 寻的足迹

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java的泛型与反射机制相关的知识,希望对你有一定的参考价值。

什么是泛型?

泛型,即“参数化类型”。顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

为什么要使用泛型?

先看如下代码:

public class GenericTest {

    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("qqyumidi");
        list.add("corn");
        list.add(100);

        for (int i = 0; i < list.size(); i++) {
            String name = (String) list.get(i); // 1
            System.out.println("name:" + name);
        }
    }
}

 在如上的编码过程中,我们发现主要存在两个问题:

  1.当我们将一个对象放入集合中,集合不会记住此对象的类型,当再次从集合中取出此对象时,改对象的编译类型变成了Object类型,但其运行时类型任然为其本身类型。

  2.因此,//1处取出集合元素时需要人为的强制类型转化到具体的目标类型,且很容易出现“java.lang.ClassCastException”异常。

使用泛型后写法:

public class GenericTest {

    public static void main(String[] args) {
        /*
        List list = new ArrayList();
        list.add("qqyumidi");
        list.add("corn");
        list.add(100);
        */

        List<String> list = new ArrayList<String>();
        list.add("qqyumidi");
        list.add("corn");
        //list.add(100);   // 1  提示编译错误

        for (int i = 0; i < list.size(); i++) {
            String name = list.get(i); // 2
            System.out.println("name:" + name);
        }
    }
}

采用泛型写法后,在//1处想加入一个Integer类型的对象时会出现编译错误,通过List<String>,直接限定了list集合中只能含有String类型的元素,从而在//2处无须进行强制类型转换,因为此时,集合能够记住元素的类型信息,编译器已经能够确认它是String类型了。

 

反射机制是什么?

 

反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

反射机制能做什么?

 

反射机制主要提供了以下功能: 

  • 在运行时判断任意一个对象所属的类;

  • 在运行时构造任意一个类的对象;

  • 在运行时判断任意一个类所具有的成员变量和方法;

  • 在运行时调用任意一个对象的方法;

  • 生成动态代理。

反射机制的实用案例

利用反射机制获取类的方法名、返回值、参数,代码如下

package fanxingText;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class FxTest {

    public static void main(String[] args) {
        
        List l = new ArrayList<>();        
        pointClassInfo(l);
        
    }

    public static void pointClassInfo(Object o){
        
        Method[] methods = (o.getClass()).getMethods();
        
        for(Method method : methods){
            System.out.print(method.getReturnType().getName() +" ");
            System.out.print(method.getName() +" " + "(");
            for(Class c : method.getParameterTypes()){
                System.out.print(c.getName()+ ",");
            }
            System.out.println(")"); 
        }
    }
}

利用反射机制将泛型为String的ArrayList中存放一个Integer类型的对象,代码如下:

package fanxingText;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class SetArrayList {

    public static void main(String[] args) throws Exception {
        
        SetArrayListOtherParam();
            
    }
    
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static void SetArrayListOtherParam() throws Exception{
        List<String> strings = new ArrayList<String>();
        
        System.out.println(strings.add("111"));
                
        Class c = strings.getClass();
        
        Method m  = c.getMethod("add",Object.class);
        
        m.invoke(strings, 1000);
        
        for(Object o : strings){
            System.out.println(o);
        }
        
        
    }

}

 

 

 

以上是关于java的泛型与反射机制的主要内容,如果未能解决你的问题,请参考以下文章

C# 中的泛型与非泛型性能

c#的泛型,委托,反射是啥?

Java泛型与集合笔记

《Java架构筑基》从Java基础讲起——泛型与反射

总结java的泛型和内部类

django rest框架中的泛型与视图集,如何选择使用哪一个?