java---反射

java—反射

java反射的概念

反射被认为是动态语言的关键,反射机制允许程序在运行期间获取任何类的内部信息。并能操作其内部方法属性。

  1. 反射机制的核心是在程序允许时动态加载类并获取类的详细信息,从而操作类或者对象的属性和方法。本质是JVM得到class对象后再通过对象进行反编译,从而获取对象的各种信息。
  2. java属于先编译后运行的语言,程序中对象的类型在编译期就确定下来了,而当程序运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载到JVM,通过反射,可以在运行时动态的创建对象并调用其属性。不需要在编译期知道运行的对象是谁。

看完后还是感觉很抽象。

*获得Class:主要有三种方法*

(1)Object–>getClass

(2)任何数据类型(包括基本的数据类型)都有一个“静态”的class属性

(3)通过class类的静态方法:forName(String className)(最常用)

三种方式中,常用第三种,第一种对象都有了还要反射干什么,第二种需要导入类包,依赖太强,不导包就抛编译错误。一般都使用第三种,一个字符串可以传入也可以写在配置文件中等多种方法。

通过反射获取构造器并创建对象创建对象

*(1)使用Class对象的newInstance()方法来创建Class对象对应类的实例。*

这种方法必须要有可以访问的构造方法才能创建对象,如果c的构造方法是private的,那么调用newInstance方法会抛出IllegalAccessException异常。

Class<?> c = String.class;

Object str = c.newInstance();

(****2)先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建对象,这种方法可以用指定的构造器构造类的实例。****

通过这种方法就算构造方法是private的也能创建对象,只需要

//获取class对象
Class<?> aClass = Class.forName("cn.luoxin88.javabase.mianshi.Myclass");
//获取构造器(包括private)
Constructor constructor = aClass.getDeclaredConstructor();
//设置private方法为可访问,不设置的话也会抛出IllegalAccessException
constructor.setAccessible(true);
//通过构造器创建对象
Myclass a = (Myclass) constructor.newInstance();

通过反射获取方法并调用

通过反射获取属性并修改其值

public class Demo2 {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException {
        Class<?> aClass = Class.forName("cn.luoxin88.javabase.mianshi.Myclass");
        //私有构造器必须通过getDeclaredConstructor获取且调用前需要设置为可访问
        Constructor constructor1 = aClass.getDeclaredConstructor();
        constructor1.setAccessible(true);
        Myclass a = (Myclass) constructor1.newInstance();
        //其他构造方法直接通过getConstructor就可以获取了,括号里面是参数对应类的class
        //需要注意的是如果方法的参数是int,则必须是int.class而不能是Interger.class
        Constructor constructor2 = aClass.getConstructor(int.class);
        Myclass b = (Myclass) constructor2.newInstance(3);
        //方法的获取与调用,获取和构造器差不多,从class对象获取,调用的时候需要指定调用该方法的对象
        // 私有方法同样需要设置为可访问后才能调用
        //参数是要获取的方法名,如果方法有参数的话还要再后面加上参数类的class对象
        Method method1 = aClass.getDeclaredMethod("f");
        method1.setAccessible(true);
        //通过invoke方法调用,第一个参数是调用该方法的对象,后面跟参数
        method1.invoke(a);
        //有参数的公共方法
        Method method2 = aClass.getMethod("f",int.class);
        method2.invoke(a,5);
        //属性的获取与修改
        //私有属性
        Field field1 = aClass.getDeclaredField("name");
        field1.setAccessible(true);
        //获取属性值要制定对象,私有属性要先设置为可访问
        System.out.println("修改前的name:"+field1.get(a));
        field1.set(a,15);
        System.out.println("修改后的name:"+field1.get(a));
        //共有属性
        Field field2 = aClass.getField("age");
        System.out.println("修改前的age:"+field2.get(a));
        field2.set(a,123);
        System.out.println("修改后的age:"+field2.get(a));
    }
}
class Myclass {
     private Myclass() {

     }
     public Myclass(int a) {

     }
     private int name = 1;
     public int age = 2;
     private void f() {
         System.out.println("private");
     }
     public void f(int a) {
         System.out.println("public" + a);
     }
}

总而言之,通过反射可以获取到类的构造器,方法和属性,并对其进行调用或者修改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Little BigUs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值