【java反射机制】

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

Class类

  • 一旦class文件被加载到内存,就会为其创建一个Class对象。任何类被使用时都会创建一个Class对象。
  • Class类是Java反射机制的基础,通过Class类,可以得到一个类的基本信息。

Class类的常用方法

方法名用法
static Class forName(String name)返回指定类名 name 的 Class 对象
Object newInstance()调用缺省构造函数,返回该Class对象的一个实例
getName()返回此Class对象所表示的实体(类、接口、数组类、基本类型或void)名称
Field[] getDeclaredFields()返回Field对象的一个数组

如何获得类的Class对象

package com.ffyc.javareflect;

public class Test1 {
    public static void main(String[] args) throws ClassNotFoundException {
        //以前使用类,已知类名,new创建对象,调用对象成员

        //User user = new User();
        //user.eat();

        //使用反射机制时,只知道类的名称(包名+类名)
        String classname = "com.ffyc.javareflect.User";

       //如何类的信息? 可以通过Class 类来获得类中的信息

        //如何获得类的class对象?
        //方式1:
        Class clazz1 = Class.forName(classname);
        System.out.println(clazz1);

        //方式2:
        Class clazz2 = User.class;
        System.out.println(clazz1 == clazz2);

        //方式3:
        User user = new User();
        Car car = new Car();
        Class clazz3 = user.getClass();
        Class clazz4 = car.getClass();
        clazz3.getFields();
        clazz4.getFields();

        System.out.println(clazz1==clazz3);
    }
}

获得Field实例

package com.ffyc.javareflect;

import java.lang.reflect.Field;
import java.sql.SQLOutput;
import java.util.HashMap;

public class Test3 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
         /*
           java中创建对象的方式:
             1.new
             2.反序列化
             3.反射机制
             4.对象克隆
         */


        //使用反射机制时,只知道类的名称(包名+类名)
        String classname = "com.ffyc.javareflect.User";
        //String classname = "com.ffyc.javareflect.Car";

        //1.通过类名 获得到类的Class对象
        Class aClass = Class.forName(classname);

        //2.通过类的Class对象,创建对象
        Object object = aClass.newInstance();

        //获得类中成员变最
        //Field accountFiled = aClass.getField("account");//获得指定名称的公共的成员变最
        /*Field accountFiled = aClass.getDeclaredField("account");//获得指定名称的成员变最,包含私有的
          accountField.setAccessible(true):
          accountFiled.set(object, "admin");
        System.out.println();*/

        HashMap<String,String> map = new HashMap<>();
                               map.put("account", "admin");
                               map.put("password", "1111");

        Field[] declaredFields = aClass.getDeclaredFields();//获得类中所有的成员变量
        for(Field field : declaredFields){
            field.setAccessible(true);//允许访问操作私有属性,不建议
            field.set(object,map.get(field.getName()));
        }
        System.out.println(object);
    }
}

Field类的作用

  • Field类将类的属性进行封装,可以获得属性的基本信息、属性的值,也可以对属性进行赋值.
  • getName:返回属性的名字
  • set:设置属性值
    获得Method实例
package com.ffyc.javareflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test4 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
          /*
           java中创建对象的方式:
             1.new
             2.反序列化
             3.反射机制
             4.对象克隆
         */


        //使用反射机制时,只知道类的名称(包名+类名)
        String classname = "com.ffyc.javareflect.User";
        //String classname = "com.ffyc.javareflect.Car";

        //1.通过类名 获得到类的Class对象
        Class aClass = Class.forName(classname);

        //2.通过类的Class对象,创建对象
        Object object = aClass.newInstance();

        //获得类中成员方法
        Method method = aClass.getMethod("eat" );
        //调用访问
        method.invoke(object);
    }
}

Method类的作用

  • Method类将类中的方法进行封装,可以动态获得方法的信息,例如:
    getName:获得方法名字
    getParameterTypes:获得方法参数类型
  • 除了动态获得方法信息外,Method还能动态调用某一个对象的具体方法
    invoke(Object obj, Object… args) :使用obj调用该方法,参数为args

反射案例

自定义java对象转json工具类

package com.ffyc.javareflect;

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

public class JsonUtil {
    public static String objectToJson(Object object) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class clazz = object.getClass();
        String json = "{";
        //获取类中所有属性
        Field[]  declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields){
            //生成属性get方法名字
            json += field.getName()+":";
            String getmethod = "get"+field.getName().substring(0, 1).toUpperCase()+field.getName().substring(1);
            //获得方法对象
            Method method = clazz.getMethod(getmethod);
            //调用方法
            String value = (String)method.invoke(object);
            //把属性名和值拼接成键值
            json += field.getName()+":"+value+",";
        }
        json = json.substring(0, json.length()-1);//去掉多余的逗号
        json +="}";
        return json;//{属性:值,属性:值}
    }

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        user.setAccount("admin");
        user.setPassword("1111");

        Car car = new Car();
        car.setName("宝马");
        car.setColor("红色");

        System.out.println(JsonUtil.objectToJson(user));
        System.out.println(JsonUtil.objectToJson(car));
    }
}


package com.ffyc.javareflect;

public class User {
    private String account;
    private String password;

    public User() {
        System.out.println("User无参构造");
    }

    private User(String account, String password) {
        this.account = account;
        this.password = password;
        System.out.println("User有参构造方法");
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        System.out.println("setaccount");
        if(account!=null)
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        System.out.println("setpassword");
        this.password = password;
    }

    public void eat() {
        System.out.println("用户吃东西");
    }

    @Override
    public String toString() {
        return "User{" +
                "account='" + account + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}


package com.ffyc.javareflect;

public class Car {
    private String name;
    private String color;

    public Car() {
    }

    public Car(String name, String color) {
        this.name = name;
        this.color = color;
    }

    public String getName() {
        return name;
    }

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

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

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

反射的优缺点

优点:
1.增加程序的灵活性,可以在运行的过程中动态对类进行修改和操作
2.提高代码的复用率,比如动态代理
3.可以在运行时轻松获取任意一个类的方法、属性,并且还能通过反射进行动态调用

缺点:
1.反射会涉及到动态类型的解析,导致性能要比非反射调用更低
2.使用反射技术通常要在一个没有安全限制的程序运行
3.反射可以绕过一些限制访问的属性或者方法,可能会导致破坏代码本身的抽象性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值