为了账号安全,请及时绑定邮箱和手机立即绑定

反射Reflect知识点小记(内容整理自课程视频)

标签:
Java

Class类

  1. 万事万物皆对象。
    类也是对象,类是java.lang.Class类的实例对象。 任何一个类都是Class的实例对象,这个实例对象有三种表示方式:
    • 第一种表示方式:实际上在告诉我们任何一个类都有一个隐含的静态成员变量class。
      Class c1 = Foo.class; //已知类名
    • 第二种表达方式,已知该类的对象,通过getClass方法。
      Class c2 = foo1.getClass(); //已知对象名
    • Class c3 = null;
      c3 = Class.forName("com.imooc.reflect.Foo");这里要写类的全名,也就是包含包名。

==c1,c2表示了Foo类的类类型(class type)。总之,类是对象,是Class类的实例对象,这个对象我们称之为该类的类类型。如上面所举的例子,Foo类的对象是Foo自身的实例对象(例如foo1),Foo类的类类型是指Class类的对象。==
==Foo foo = (Foo)c1.newInstance();需要强制类型转换。注意,Foo类必须有自己的无参构造方法!这是前提条件。==

Java动态加载类

Class.forName("类的全称")

  • 不仅表示了类的类类型,还代表了动态加载类
  • 要区分编译、运行
  • 编译时刻加载类是静态加载类(new的方式)、运行时刻加载类是动态加载类
  • new创建对象是静态加载类,在编译时刻就需要加载所有的可能使用到的类,通过动态加载类可以解决该问题。功能性的类一般使用动态加载类。

Java获取方法

  • 基本的数据类型、void关键字都有类类型。
  • Class类的基本API操作
public static void printClassMessage(Object obj){
        //要获取类的信息,首先要获取类的类类型
        Class c = obj.getClass();//传递的是哪个子类的对象,c就是该子类的类类型
        //获取类的名称
        System.out.println("类的名称是"+c.getName());
        /*万事万物皆对象
         * Method类——方法对象
         * 一个成员方法就是一个Method对象
         * Method类封装了对成员方法的操作
         * getMethods()方法获取的是所有的public的函数,包括从父类继承而来的
         * getDelaredMethods()获取的是所有该类自己声明的方法,不问访问权限
         */
        Method[] ms = c.getMethods();//或者c.getDeclaredMethods()
        for(int i=0;i<ms.length;i++){

            //得到方法的返回值类型的类类型
            Class returnType = ms[i].getReturnType();
            System.out.print(returnType.getName()+" ");//返回值类型的名字
            //得到方法的名称
            System.out.print(ms[i].getName()+"(");
            //获取参数类型--->得到的是参数列表的类型的类类型
            Class[] paramTypes = ms[i].getParameterTypes();
            for (Class class1 : paramTypes) {
                System.out.println(class1.getName()+",");
            }
            System.out.println(")");

        }
    }

Java获取成员变量和构造函数

Filed[] fs = c.getFileds();//获取所有public的成员变量的信息
Filed[] fs = c.getDeclaredFields();//获取该类自己声明的成员变量信息
for(Field field :fs){
   Class FieldType = field.getType();//获取成员变量的类型的类类型
   String typeName = filedType.getName();//获取成员变量类型的名称
   String fieldName = field.getName();//得到成员变量的名称
   System.out.println(typeName+""+fieldName);
}
构造函数也是对象,java.lang.Constructor中封装了构造函数的信息。
Constructor[] cs = c.getConstructors();//获取所有的public构造函数方法
Constructor[] cs = c.getDecleardConstructors();//获取所有的构造函数
for(Constructor constructor :cs){
 System.out.print(constructor.getName()+"(");//但其实构造函数无返回值
//获取构造函数的参数列表------->得到的是参数列表的类类型
Class[] paramTypes = constructor.getParameterTypes();
for(Class class1:paramTypes){
 System.out.print(class.getName()+",");
}
   System.out.println(+")");
}

方法的反射

public class MethodDemo1{
     public static void main(String[] args){
   //获取一个方法就是获取类的信息,获取类的信息首先就要获取类的类类型
   A  a1 = new A();
   Class c = a1.getClass();
   //获取方法名称和参数列表来决定  getMethod获取的是public的方法
  //getDelcaredMethod自己声明的方法

  //Method m =   c.getMethod("print",new Class[]{int.Class,int.Class});
   Method m = c.getMethod("print",int.Class,intClass);

   //方法的反射操作 用m对象来进行方法的调用和a1.print调用效果一样
 //方法如果没有返回值返回null,有返回值返回具体的返回值 
 Object o = m.invoke(a1,new Object[]{10,20});
    }
}

class A{
    public void print(int a,int b){
        System.out.println(a+b);
    }

    public void print(String a,String b){
    }

}

通过反射了解集合泛型的本质

ArrayList list = new ArrayList();//能放任何类型,因为没有泛型    
        ArrayList<String> list1 = new ArrayList<String>();//只能放String类型
        //list1.add("hello");
        //list1.add(20);错误的,集合的泛型就是用来防止错误输入的

        Class c1 = list.getClass();
        Class c2 = list1.getClass();

        System.out.println(c1==c2);//反射的操作都是编译之后的操作
        /*
         * c1==c2 返回true,说明编译之后,集合的泛型是去泛型化的!也就是说集合没有泛型了!
         * Java中集合的泛型,是防止错误输入的,只在编译阶段有效
         * 绕过编译就无效了
         * 验证:我们可以通过方法的反射操作,来绕过编译
         */

        try {
            Method m = c2.getMethod("add", Object.class);//这里不要写成String.class,不然无法向list1添加整型
            m.invoke(list1, "hello");

            m.invoke(list1, 20);//绕过编译操作,就绕过了泛型

            System.out.println(list1.size());
            System.out.println(list1);
            /*
            for (String string : list1) {
                System.out.println(string);
            }*///现在不能这样遍历了,会有类型转换错误。int不能转化为String

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
                }
点击查看更多内容
3人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
2
获赞与收藏
53

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消