java反射机制

博客介绍了Java反射机制,它允许程序在运行时获取类的内部信息,能让代码更灵活、降低耦合度,但使用不当会消耗大量资源,还会破坏Java封装特性。同时列举了新建实体类、获取Class的三种方式,以及Class类获取成员变量、方法等的多种方法并给出实例演示。

我们知道反射机制允许程序在运行时取得任何一个已知名称的class的内部信息,包括包括其modifiers(修饰符),fields(属性),methods(方法)等,并可于运行时改变fields内容或调用methods。那么我们便可以更灵活的编写代码,代码可以在运行时装配,无需在组件之间进行源代码链接,降低代码的耦合度;还有动态代理的实现等等;但是需要注意的是反射使用不当会造成很高的资源消耗!

注意:反射破坏了java的封装特性

新建一个实体类:

package com.yitian.javabase;

/**
 * @author :yitianren
 * @date :Created in 2019-5-21 14:22
 * @description:
 * @modified By:
 * @version: $
 */
public class Perple {
    private int age;
    private String name ;

    private final static  int iphone=123;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Perple{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

    public final   void  say(){
        System.out.println("我被调用了!");
    }

    public final   void  outNum (int i){
        System.out.println("反射调用的数字为:"+i);
    }
}

获取Class的三种方式:

//1、通过对象调用 getClass() 方法来获取,通常应用在:比如你传过来一个 Object
//  类型的对象,而我不知道你具体是什么类,用这种方法
  Perper p1 = new Perper ();
  Class c1 = p1.getClass();
        
//2、直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高
//  这说明任何一个类都有一个隐含的静态成员变量 class
  Class c2 = Perper .class;
        
//3、通过 Class 对象的 forName() 静态方法来获取,用的最多,
//   但可能抛出 ClassNotFoundException 异常
  Class c3 = Class.forName("com.yitian.javabase.Perper ");

通过 Class 类获取成员变量、成员方法、接口、超类、构造方法等

查阅 API 可以看到 Class 有很多方法:

  getName():获得类的完整名字。
  getFields():获得类的public类型的属性。
  getDeclaredFields():获得类的所有属性。包括private 声明的和继承类
  getMethods():获得类的public类型的方法。
  getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类
  getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。
  getConstructors():获得类的public类型的构造方法。
  getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。
  newInstance():通过类的不带参数的构造方法创建这个类的一个对象。

实例演示:

package com.yitian.javabase;



import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author :yitianRen
 * @date :Created in 2019-5-21 14:17
 * @description:
 * @modified By:
 * @version: $
 */
public class Reflect {


    public static void main(String[] args) throws Exception {

        Class c1=Perple.class;
        Object o=c1.newInstance();//实例化对象

        System.out.println("类名:"+c1.getName());


        Field[] files=c1.getFields();
        for (int i = 0; i < files.length ; i++) {
            System.out.println("属性:+"+files[i].getName());
        }

        Field[] fields1=c1.getDeclaredFields();
        for (int i = 0; i < fields1.length ; i++) {
            System.out.println("包含私有属性:+"+fields1[i].getName());
        }

        //获得类的所有方法。
        Method[] allMethods = c1.getDeclaredMethods();
        for(Method method : allMethods) {//获取特定的方法

            //System.out.println(method.getName());//work say
            if(method.getName().equals("say")){
                method.invoke(o);
                System.out.println("say方法");
            }

            //带参数的方法  反射调用
            if(method.getName().equals("outNum")){
                method.invoke(o,1);
                System.out.println("outNum方法");
            }
        }


        Field f=c1.getDeclaredField("iphone");
        f.setAccessible(true);//私有方法可以被调用
        System.out.println("获取私有方法iphone:"+f.getName());



        //Method me=c1.
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值