Java反射基础入门

目录

一、基本概念

1.1 反射的含义

1.2 反射的过程

二、获取成分

2.1 获取Class对象

2.2 获取构造器对象

2.3 获取成员变量

2.4 获取成员方法

三、使用场景


一、基本概念

1.1 反射的含义

加载类,并允许以编程的方式获取类中的各种成分(方法、成员变量、构造器等等)

1.2 反射的过程

加载类,获得类的字节码(Class对象)

获取类的构造器(Constructor对象)

获取类的成员变量(Field对象)

获取类的成员方法(Method对象)

对得到的类的属性进行操作(成员变量赋值、new对象、执行私有方法)

二、获取成分

2.1 获取Class对象

①直接获取对象(建议优先使用)

Class myClass = 类名.Class

②调用Class提供方法

forName方法

③Object提供方法

getClass

2.2 获取构造器对象

关键方法:

--获取定义的构造器方法 getDeclaredConstructor

--利用获取的构造器方法new一个对象(可使用强制类型转换) yourGetConstructor.newInstance

package com.study;

import java.lang.reflect.Constructor;

import org.junit.Test;

public class myCatTest {

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Test
    public void test() throws Exception {
        Class c = myCat.class;
        // 获取无参构造器
        Constructor constructor1 = c.getDeclaredConstructor();
        constructor1.setAccessible(true);//强制不检查访问权限
        myCat cat1 = (myCat) constructor1.newInstance();
        System.out.println(cat1);
        // 获取有参构造器
        Constructor constructor2 = c.getDeclaredConstructor(String.class, int.class);
        constructor2.setAccessible(true);
        myCat cat2 = (myCat) constructor2.newInstance("加菲猫", 2);
        System.out.println(cat2);

    }
}

2.3 获取成员变量

关键方法:

--获取定义的成员变量(所有权限均可) getDeclaredField,getDeclaredFields

--设置访问权限 yourGetField.setAccessible

--对获取的成员变量进行赋值 yourGetConstructor.set

// myCat类
package com.study;

public class myCat {
    private String name;
    private int age;
    public myCat(){
        System.out.println("这是一个无参数的构造器");
    }
    public myCat(String name,int age){
        System.out.println("这是一个有参数的构造器");
        this.name = name;
        this.age = age;
    }


    @Override
    public String toString() {
        return "myCat [name=" + name + ", age=" + age + "]";
    }
}
// myCat测试类,使用反射获取成员变量
package com.study;

import java.lang.reflect.Field;
import org.junit.Test;

public class myCatTest {

    @SuppressWarnings({ "rawtypes" })
    @Test
    public void test() throws Exception {
        Class c = myCat.class;

        // 获取成员变量
        Field[] myField = c.getDeclaredFields();
        for (Field field : myField) {
            System.out.println(field);
        }
        myCat newCat = new myCat("中华田园猫", 10);
        // 获取单个成员变量并赋值
        Field myField2 = c.getDeclaredField("name");
        myField2.setAccessible(true);
        myField2.set(newCat, "加菲猫");
    }
}

2.4 获取成员方法

关键方法:

--获取定义的成员方法(所有权限均可) getDeclaredMethod

--设置访问权限 yourGetMethod.setAccessible

--运行获取的成员方法 yourGetMethod.invoke

// myCat类
package com.study;

public class myCat {
    private String name;
    private int age;
    public myCat(){
        System.out.println("这是一个无参数的构造器");
    }
    public myCat(String name,int age){
        System.out.println("这是一个有参数的构造器");
        this.name = name;
        this.age = age;
    }
    // 两个私有同名方法
    @SuppressWarnings("unused")
    private void eat(){
        System.out.println(this.name+"正在吃猫粮");
    }
    @SuppressWarnings("unused")
    private String eat(String food){
        return this.name+"正在吃"+food;
    }
    @Override
    public String toString() {
        return "myCat [name=" + name + ", age=" + age + "]";
    }
}
// myCat测试类,获取成员方法
package com.study;

import java.lang.reflect.Method;
import org.junit.Test;

public class myCatTest {

    @SuppressWarnings({ "rawtypes" })
    @Test
    public void test() throws Exception {
        Class c = myCat.class;

        // 获取成员方法并打印
        Method[] myMethod = c.getDeclaredMethods();
        for (Method method : myMethod) {
            System.out.println(method);
        }
        // 获取成员方法并单独执行
        myCat newCat = new myCat("中华田园猫", 10);

        @SuppressWarnings("unchecked")
        Method hasMethod = c.getDeclaredMethod("eat", String.class);
        // 禁止检查访问权限
        hasMethod.setAccessible(true);
        // 直接执行
        Object rs = hasMethod.invoke(newCat);
        System.out.println((String) rs);

        @SuppressWarnings("unchecked")
        Method noMethod = c.getDeclaredMethod("eat");
        hasMethod.setAccessible(true);
        noMethod.invoke(newCat);

    }
}

三、使用场景

获取类的所有成分并操作

破坏类的封装性,实现直接使用

配合制作Java框架

配合单元测试的使用(有时候需要达到固定的单元测试覆盖率,但某些私有方法无法在外部执行,可以使用反射直接执行私有方法)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值