java中的反射机制

java中的反射机制

  • 什么是反射 为什么要使用反射 什么情况下使用反射
  • 获取Class对象的常用方法
  • 利用反射获取类的构造方法
  • 利用反射获取类的方法
  • 利用发射获取类的属性(成员变量)
  • 利用反射创建对象
  • 利用反射调用类的方法
  • 利用反射访问类的属性

什么是反射 为什么要使用反射 什么情况下使用反射

反射机制指的是程序在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。

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

jdk 1.6 版本引入了 反射机制,就是用来动态的创建对象,调用类的方法,或者访问类的属性的一种机制(思路)就相当于用反射给 java静态语言打了动态语言的补丁,有了反射之后就很容易 解决上述问题了

java 是静态语言

静态语言是指在编译时变量的du数据类型即可zhi确定的语言,多数静态类型语言要求在使用变量之前必须声明数据类型。例如:C++、Java、Delphi、C#等。
动态语言是在运行时确定数据类型的语言。变量使用之前不需要类型声明,通常变量的类型是被赋值的那个值的类型。例如:Python、Ruby、Perl等。
现在一般很少这样划分程序语言了

js 是动态语言 js 就能在程序的运行期 根据指定的参数创建指定的对象或者调用方法或者访问属性

动态类型语言 一般是脚本语言,比如说Perl、Ruby、Python、PHP、JavaScript,可以更快地编写代码,不必每次都指定类型,做type checking是在run-time的时候去做的。优点是可能代码开发快,但是维护难(但是脚本语言平常写的代码量应该不太多,还比较好debug和修改)

获取Class对象的常用方法

每个java的类在jvm加载之后 都会自动在内存中创建该类对应的Class对象

我们要做的事就是使用特定的方式 去获取这个对象就可以了

package com.aaa.demo;

/**
 * @Author Lst
 * @Date 2021/1/4 18:25
 * @Version 1.0
 * 获取class对象的三种方式
 */
public class Person01 {
    public static void main(String[] args) throws ClassNotFoundException {
        // 第一种方式 直接访问类的class属性
        Class clazz01 = Person01.class;
        System.out.println(clazz01);
        // 第二种方式 调用类的对象getClass方法
        Person01 person01 = new Person01();
        Class clazz02 = person01.getClass();
        System.out.println(clazz02);
        // 第三种方式 调用 class 类的静态方法 forName
        Class clazz3 = Class.forName("com.aaa.demo.Person01");
        System.out.println(clazz3);
    }
}

利用反射或者类的构造方法

package com.aaa.demo;

import java.lang.reflect.Constructor;

/**
 * @Author Lst
 * @Date 2021/1/5 10:39
 * @Version 1.0
 * 利用反射获取类的构造方法对象
 */
public class Person02 {

    public Person02() {
        System.out.println("默认无参构造");
    }

    public Person02(String name) {
        System.out.println("默认有一个参数的构造方法");
    }

    private Person02(String name, Integer age) {
        System.out.println("有两个参数的私有构造方法");
    }

    public static void main(String[] args) throws NoSuchMethodException {
        // 获取类的class对象
        Class clazz = Person02.class;
        System.out.println("获取类的所有的公共构造方法");
        Constructor[] constructors = clazz.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        System.out.println("打印类所有的声明的构造方法");
        Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }

        // 获取指定的构造方法的对象
        Constructor constructor = clazz.getConstructor(String.class);
        System.out.println("获取有一个参数的公共的构造方法");
        System.out.println(constructor);
        // 获取 指定的构造方法
        Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class, Integer.class);
        System.out.println("获取有两个参数的私有构造方法");
        System.out.println(declaredConstructor);

    }

}

利用反射获取类的方法

package com.aaa.demo;

import java.lang.reflect.Method;

/**
 * @Author Lst
 * @Date 2021/1/5 13:40
 * @Version 1.0
 * 利用反射获取类的方法
 */
public class Person03 {

    public void info() {
        System.out.println("没有参数的公共的方法");
    }
    public void info(String name) {
        System.out.println("只有一个参数的公共方法");
    }

    private void info(String name, Integer age) {
        System.out.println("有两个参数的私有方法");
    }

    public static void main(String[] args) throws NoSuchMethodException {
        // 获取类的 class 对象
        Class clazz = Person03.class;
        // 获取类的方法对象
        System.out.println("能获取到所有公共的方法,包含父类中的公共的方法");
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("获取类声明过 所有的方法, 不包含父类中的方法");
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        System.out.println("获取类的有一个 String类型参数并且方法名为 info 的公共的方法");
        Method method = clazz.getMethod("info",String.class);
        System.out.println(method);
        System.out.println("获取类的有 String类型参数跟 Integer类型的参数 私有的方法名为 info");
        Method method1 = clazz.getDeclaredMethod("info",String.class,Integer.class);
        System.out.println(method1);


    }

}

利用发射获取类的属性(成员变量)

package com.aaa.demo;

import java.lang.reflect.Field;
import java.util.Arrays;

/**
 * @Author Lst
 * @Date 2021/1/5 13:58
 * @Version 1.0
 * 利用发射获取类的属性(成员变量)
 */
public class Person04 extends Person01 {

    private String name;

    public Integer age;

    public static void main(String[] args) throws Exception {
        // 获取类的Class对象
        Class clazz = Person04.class;
        // 获取属性的方法
        System.out.println("获取所有公共的属性,也可以获取父类中的公共属性");
        Field[] clazzFields = clazz.getFields();
        for (Field clazzField : clazzFields) {
            System.out.println(clazzField);
        }
        System.out.println("获取所有公共的属性,不包含父类中的公共属性");
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        // 获取指定属性名叫age的公共的属性
        System.out.println("获取属性名为age");
        Field field = clazz.getField("age");
        System.out.println(field);
        // 获取指定属性名叫name的私有的属性
        System.out.println("获取指定属性名叫name的私有的属性");
        Field name = clazz.getDeclaredField("name");
        System.out.println(name);
    }
}

利用反射创建对象

package com.aaa.demo;

import java.lang.reflect.Constructor;

/**
 * @Author Lst
 * @Date 2021/1/5 14:13
 * @Version 1.0
 * 利用反射创建对象
 */
public class Person05 {

    public Person05() {
        System.out.println("默认无参构造");
    }

    public Person05(String name) {
        System.out.println("有一个String 类型参数的公共构造");
    }
    

    public static void main(String[] args) throws Exception {
        // 获取类的Class对象
        Class clazz = Class.forName("com.aaa.demo.Person05");
        // 第一种方式创建对象  类必须要有默认无参构造方法
        Object p1 = clazz.newInstance();
        System.out.println(p1);
        // 第二种方式  通过调用类的构造方法对象的方法
        Constructor constructor = clazz.getConstructor(String.class);
        Object p2 = constructor.newInstance("张三");
        System.out.println(p2);


    }
}

利用反射调用类的方法

package com.aaa.demo;

import java.lang.reflect.Method;

/**
 * @Author Lst
 * @Date 2021/1/5 13:40
 * @Version 1.0
 * 利用反射调用类的方法
 */
public class Person06 {

    public String info() {
        System.out.println("没有参数的公共的方法");
        return "李松涛";
    }
    public void info(String name) {
        System.out.println("只有一个参数的公共方法");
    }

    private void info(String name, Integer age) {
        System.out.println("有两个参数的私有方法");
    }

    public static void main(String[] args) throws Exception {
        // 获取类的class对象
        Class clazz = Person06.class;
        // 创建Person06对象
        Object person06 = clazz.newInstance();
        // 获取Person06默认无参的 info方法
        Method infoMethod = clazz.getMethod("info");
        // 调用infoMethod 的方法
        Object result = infoMethod.invoke(person06);
        System.out.println(result);
        // 调用有参数的 方法
        Method info = clazz.getDeclaredMethod("info", String.class, Integer.class);
        info.invoke(person06, "张三", 19);

    }

}

利用反射访问类的属性

package com.aaa.demo;

import java.lang.reflect.Field;

/**
 * @Author Lst
 * @Date 2021/1/5 13:58
 * @Version 1.0
 * 利用反射访问类的属性
 */
public class Person07 extends Person01 {

    private String name;

    public Integer age;

    public static void main(String[] args) throws Exception {
        // 获取类的Class对象
        Class clazz = Person07.class;
        // 创建对象
        Object o = clazz.newInstance();
        // 获取类的属性名 为age的属性
        Field age = clazz.getField("age");
        // 为age的filed对象设置值
        age.set(o, 19);
        // 获取 age 属性的值
        System.out.println(age.get(o));
        Class clazz02 = Person01.class;
        Field info = clazz02.getField("info");
        // 获取私有的属性
        Field name = clazz.getDeclaredField("name");
        // 设置忽略访问级别
        name.set(o, "zhangsan");
        System.out.println(name.get(o));
    }
}

再别的类访问 私有的属性 跟方法的话

package com.aaa.demo;

import java.lang.reflect.Field;

/**
 * @Author Lst
 * @Date 2021/1/5 19:31
 * @Version 1.0
 */
public class Person08 {
    public static void main(String[] args) throws Exception{
        // 获取类的对象
        Class clazz = Person07.class;
        // 创建对象
        Object o = clazz.newInstance();
        // 获取类的属性名age的属性
        Field age = clazz.getDeclaredField("name");
        // 设置忽略
        age.setAccessible(true);
        age.set(o,"lyx");
        System.out.println(age.get(o));

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值