Java 反射

目录

 

简介

Class类

反射--获取Class对象的三种方式:

反射--获取指定构造方法创建一个对象

反射--获取属性值,为指定属性赋值

反射--普通方法的调用

反射--static方法调用

反射--破坏泛型检查

关于泛型--请参考博文


简介

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

反射机制中,一个类的属性,方法,构造方法,以及注释 都有与之对应的类对其进行描述,反射的核心思想就是把原有类的属性、方法、构造方法、注释乃至包命用一个又一个的类去拆解。

 

Class类

  1. final类。
  2. 运行中的类、接口是Class类的实例。
  3. 枚举是一种类、注解是一种接口、数组将被映射成一个Class类对象,具有相同元素类型与维度的数组将共享该对象。
  4. boolean, byte, char, short, int, long, float, and double,void 也是Class的实例对象。
  5. Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass 方法自动构造的。也就是这不需要我们自己去处理创建,JVM已经帮我们创建好了。

 

反射--获取Class对象的三种方式:

(别说创建Class对象、因为Class类的对象早就在内存中存在了,我们所要做的就是拿到这些对象直接使用)

package com.knowledge.system.java_system.reflection_system.bok_instance;

public class Student {
    private Integer age;
    private String name;
    private String address;
    private boolean sex;

    public Student() {
        System.out.println("公有无参构造函数");
    }

    private  Student(Integer age) {
        this.age = age;
        System.out.println("私有一个参数构造函数");
    }

    protected Student(String name) {
        this.name = name;
        System.out.println("受保护一个参数构造函数");
    }

    public Student(boolean sex) {
        this.sex = sex;
        System.out.println("公有一个参数构造函数");
    }

    public Student(Integer age, String name, String address, boolean sex) {
        this.age = age;
        this.name = name;
        this.address = address;
        this.sex = sex;
    }

    public void testFun1(String msg){
        System.out.println(msg);
    }

    public void testFun2(String msg){
        System.out.println(msg);
    }

    public void testFun3(String msg){
        System.out.println(msg);
    }

    public Integer getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public boolean isSex() {
        return sex;
    }

    public void setSex(boolean sex) {
        this.sex = sex;
    }

    public static void main(String[] args) {
        System.out.println("main 方法执行了。");
    }

    public static void testMain(String msg){
        System.out.println("static  方法执行了,入参"+msg);
    }
}
package com.knowledge.system.java_system.reflection_system.bok_instance;

import com.alibaba.fastjson.JSON;
import lombok.SneakyThrows;
import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * @program: demo-pom
 * @description:
 * @author: bo.hu
 * @create: 2020-03-05 16:59
 **/

public class ReflectionTest {
    @Test
    public void testGetClassObject(){
        Student student=new Student();
        Class clz=student.getClass();//对象角度---不常用,对象都有了还反射干啥
        Class clz2=Student.class;//类角度---业务开发中常用(但要导包,依赖太强,不导包编译会出问题)
        Class clz3=null;//静态方法角度---常用(全路径名可以通过配置文件搞进去)
        try {
            clz3=Class.forName("com.knowledge.system.java_system.reflection_system.bok_instance.Student");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println(clz.getName());
        System.out.println(JSON.toJSONString(clz3.getPackage()));
        System.out.println("constructors  "+JSON.toJSONString(clz.getDeclaredConstructors()[0]));
        System.out.println("fields  "+JSON.toJSONString(clz.getDeclaredFields()[0]));
        System.out.println("method  "+JSON.toJSONString(clz.getDeclaredMethods()[0]));
        System.out.println("annotation  "+JSON.toJSONString(clz.getDeclaredAnnotations()[0]));
    }

}

 

反射--获取指定构造方法创建一个对象

  1. Constructor  :可以调用任何构造方法,可强行访问

  2. Class.newInstance:只能够调用   共有  无参构造方法。当无参方法私有时,报错:java.lang.IllegalAccessException

    @Test
    public void testConstructors() throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException {
        //通过反射获取指定的构造方法--主要用来创建对象
        Class clz=Student.class;
        Constructor con=clz.getDeclaredConstructor(Integer.class);
        if(!con.isAccessible()){
            con.setAccessible(true);
        }
        Student student= (Student) con.newInstance(23);
        System.out.println("student:"+JSON.toJSONString(student));

        Student student1= (Student) clz.newInstance();
        System.out.println("student1:"+JSON.toJSONString(student1));
    }

 

反射--获取属性值,为指定属性赋值

    @Test
    public void testField() throws NoSuchFieldException, IllegalAccessException {
        //获取指定属性值
        Student student=new Student();
        student.setAge(20);
        Class clz=Student.class;
        Field f=clz.getDeclaredField("age");
        if(!f.isAccessible()){
            f.setAccessible(true);
        }
        Object value=f.get(student);
        System.out.println(value);
        //设置指定属性值
        Field field=clz.getDeclaredField("name");
        if(!field.isAccessible()){
            field.setAccessible(true);
        }
        field.set(student,"afgahgdahgahdhas");
        System.out.println(JSON.toJSONString(student));
    }

 

反射--普通方法的调用

   @Test
    public void testMethod() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class clz=Student.class;
        Student student=new Student();
        Method method=clz.getDeclaredMethod("setName",String.class);
        if(!method.isAccessible()){
            method.setAccessible(true);
        }
        method.invoke(student,"adghashasd;gasdhgasdfgiophpuioh");
        System.out.println(JSON.toJSONString(student, SerializerFeature.WriteMapNullValue));
    }

 

反射--static方法调用

    @Test
    public void testMethod() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class clz=Student.class;
        Student student=new Student();
        Method method=clz.getDeclaredMethod("testMain", String.class);
        if(!method.isAccessible()){
            method.setAccessible(true);
        }
        method.invoke(null,"adghashasd;gasdhgasdfgiophpuioh");
        System.out.println(JSON.toJSONString(student, SerializerFeature.WriteMapNullValue));
    }

    @Test
    public void testMain() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class clz=Student.class;
        Method m1=clz.getDeclaredMethod("main",String[].class);
        m1.invoke(null,(Object)new String[]{"a","a","a"});
    }

 

反射--破坏泛型检查

    @SneakyThrows
    @Test
    public void testTEF(){
        List <String> arrayList=new ArrayList <>();
        arrayList.add("adddd");
        arrayList.add("bbbbbb");
        Class clz=arrayList.getClass();
        Method m=clz.getDeclaredMethod("add",Object.class);
        m.invoke(arrayList,1000);
        System.out.println(JSON.toJSONString(arrayList));
    }

关于泛型--请参考博文

Java 泛型使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值