Java - 反射

这篇博客介绍了Java中的反射机制,包括其用途,如检查和修改运行时应用程序的行为。详细阐述了获取Class对象的三种方式:Class.forName()、getClass()以及使用.class。接着讨论了如何通过反射获取属性,如.getMethods(), .getInterfaces(), .getSuperclass(), .getConstructors(), .getFields(), .getDeclaredMethods()和.getDeclaredFields()等,并提到如何通过.newInstance()创建类实例。对于访问私有属性和方法,提到了setAccessible(true)用于修改权限。" 50512802,5560785,Cocos Studio 制作帧动画详解,"['游戏开发', 'Cocos2d', '动画制作']

Java - 反射

1. 反射用途

反射通常由需要检查或修改Java虚拟机中运行的应用程序的运行时行为的程序使用。

2. 获取Class对象方式

  • Class.forName()   通过类的全路径名称

此种方法通过对象的全路径来获取Class的,当对象不存在时,会出现ClassNotFoundException异常

  • getClass()  通过Object类的getClass() 方法
  • .class   通过对象实例方法

 3.获取属性

  • .getMethods() 
    /**
     * Returns an array containing {@code Method} objects reflecting all the
     * public methods of the class or interface represented by this {@code
     * Class} object, including those declared by the class or interface and
     * those inherited from superclasses and superinterfaces.
     *
     * <p> If this {@code Class} object represents a type that has multiple
     * public methods with the same name and parameter types, but different
     * return types, then the returned array has a {@code Method} object for
     * each such method.
     *
     * <p> If this {@code Class} object represents a type with a class
     * initialization method {@code <clinit>}, then the returned array does
     * <em>not</em> have a corresponding {@code Method} object.
     *
     * <p> If this {@code Class} object represents an array type, then the
     * returned array has a {@code Method} object for each of the public
     * methods inherited by the array type from {@code Object}. It does not
     * contain a {@code Method} object for {@code clone()}.
     *
     * <p> If this {@code Class} object represents an interface then the
     * returned array does not contain any implicitly declared methods from
     * {@code Object}. Therefore, if no methods are explicitly declared in
     * this interface or any of its superinterfaces then the returned array
     * has length 0. (Note that a {@code Class} object which represents a class
     * always has public methods, inherited from {@code Object}.)
     *
     * <p> If this {@code Class} object represents a primitive type or void,
     * then the returned array has length 0.
     *
     * <p> Static methods declared in superinterfaces of the class or interface
     * represented by this {@code Class} object are not considered members of
     * the class or interface.
     *
     * <p> The elements in the returned array are not sorted and are not in any
     * particular order.
     *
     * @return the array of {@code Method} objects representing the
     *         public methods of this class
     * @throws SecurityException
     *         If a security manager, <i>s</i>, is present and
     *         the caller's class loader is not the same as or an
     *         ancestor of the class loader for the current class and
     *         invocation of {@link SecurityManager#checkPackageAccess
     *         s.checkPackageAccess()} denies access to the package
     *         of this class.
     *
     * @jls 8.2 Class Members
     * @jls 8.4 Method Declarations
     * @since JDK1.1
     */
  • 接口: .getInterfaces()
  • 父类: .getSuperclass()
  • 构造方法: .getConstructors()
  • 公共属性: .getFields()
  • 全部方法: .getDeclaredMethods()
  • 全部属性: .getDeclaredFields()
  • 获取反射代表类的实例: .newInstance()

调用私有属性或方法时无法直接调用,通过 setAccessible(true)  修改权限来操作

 

package reflect;

import java.io.FileReader;
import java.io.Serializable;
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.Arrays;
import java.util.Properties;

class Teacher {
    private String name;

    public void say() {
        System.out.println("开始上课!");
    }
}

class Student implements Serializable {
    private String name;
    private int age;
    private int score;

    public String pubFiled;

    public Student() {

    }

    private Student(String name) {
        this.name = name;
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void pubFun(String s) {
        System.out.println("public method!-> " + s);
    }

    public void pubFun() {
        System.out.println("public method! null");
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public String getPubFiled() {
        return pubFiled;
    }

    public void setPubFiled(String pubFiled) {
        this.pubFiled = pubFiled;
    }
}

public class ReflectDemo {

    public static void f1() throws ClassNotFoundException {
        // 通过Class.forName()
        Class<?> aClass = Class.forName("reflect.Student");
        // 通过类 .class
        Class<?> aClass1 = Student.class;
        // 通过类对象的getClass() 方法
        Student s = new Student();
        Class<? extends Student> aClass2 = s.getClass();
        // 输出
        System.out.println(aClass);
        System.out.println(aClass1);
        System.out.println(aClass2);

    }

    /**
     * 通过反射获取公共方法
     */
    public static void f2() throws ClassNotFoundException {
        Class<?> aClass = Class.forName("reflect.Student");
        Method[] methods = aClass.getMethods();
        Arrays.asList(methods).forEach(method -> System.out.println(method));
    }

    /**
     * 通过反射获取接口
     */
    public static void f3() throws ClassNotFoundException {
        Class<?> aClass = Class.forName("reflect.Student");
        Class<?>[] interfaces = aClass.getInterfaces();
//        System.out.println(Arrays.toString(methods));
        Arrays.asList(interfaces).forEach(System.out::println);
    }

    /**
     * 通过反射获取父类
     */
    public static void f4() throws ClassNotFoundException {
        Class<?> aClass = Class.forName("reflect.Student");
        Class<?> superclass = aClass.getSuperclass();
        System.out.println(superclass);
    }

    /**
     * 通过反射获取构造方法
     */
    public static void f5() throws ClassNotFoundException {
        Class<?> aClass = Class.forName("reflect.Student");
        Constructor<?>[] constructors = aClass.getConstructors();
        Arrays.asList(constructors).forEach(constructor -> {
            System.out.println(constructor);
        });
    }

    /**
     * 通过反射获公共属性
     */
    public static void f6() throws ClassNotFoundException {
        Class<?> aClass = Class.forName("reflect.Student");
        Field[] fields = aClass.getFields();
        Arrays.asList(fields).forEach(field -> System.out.println(field));
    }

    /**
     * 通过反射获全部方法
     */
    public static void f7() throws ClassNotFoundException {
        Class<?> aClass = Class.forName("reflect.Student");
        Method[] fields = aClass.getDeclaredMethods();
        Arrays.asList(fields).forEach(method -> System.out.println(method));
    }

    /**
     * 通过反射获全部属性
     */
    public static void f8() throws ClassNotFoundException {
        Class<?> aClass = Class.forName("reflect.Student");
        Field[] fields = aClass.getDeclaredFields();
        Arrays.asList(fields).forEach(method -> System.out.println(method));
    }

    /**
     * 通过反射获取实例
     */
    public static void f9() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Class<?> aClass = Class.forName("reflect.Student");
        Object instance = aClass.newInstance();
        Student s = (Student) instance;
        s.pubFun("");
    }

    /**
     * 通过反射操作属性 方法
     */
    public static void f10() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
        Class<?> aClass = Class.forName("reflect.Student");
        Student instance = (Student) aClass.newInstance();

        Field name = aClass.getDeclaredField("name");
        // 属性私有的无法直接修改 修改属性的访问权限setAccessible
        name.setAccessible(true);
        name.set(instance, "张三");
        System.out.println(instance.getName());
        Method getName = aClass.getDeclaredMethod("pubFun", String.class);
        // 如果是private 可以修改权限设置
        getName.setAccessible(true);
        getName.invoke(instance, "adsfasfd");
    }

    /**
     * 通过反射操作构造方法
     */
    public static void f11() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
        Class<?> aClass = Class.forName("reflect.Student");
        Student instance = (Student) aClass.newInstance();
        // 获取指定构造方法,根据参数类型
        Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(String.class);
        // 私有构造 修改权限
        declaredConstructor.setAccessible(true);
        Student zhangsang = (Student) declaredConstructor.newInstance("zhangsang");
        System.out.println(zhangsang.getName());

    }

    /**
     * 通过反射 运行时创建实例和调用方法
     * 动态加载类  和方法
     */
    public static void f12() throws Exception {
        // 通过配置文件获取要创建的类和方法
        Properties properties = new Properties();
        properties.load(new FileReader("src\\test\\java\\reflect\\class.txt"));
        String classname = properties.getProperty("classname");
        String methodname = properties.getProperty("methodname");
        Class<?> aClass = Class.forName(classname);
        Method declaredMethod = aClass.getDeclaredMethod(methodname);
        declaredMethod.invoke(aClass.newInstance());
    }

    /**
     * 通过反射跳过泛型检查
     */
    public static void f13() throws Exception {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        Class<? extends ArrayList> aClass = list.getClass();
        Method add = aClass.getDeclaredMethod("add", Object.class);
        add.invoke(list, "str");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        System.out.println(list);
    }

    /**
     * 通过反射 给对象任意属性赋值
     */
    public static void f14() throws Exception {
        Student s = new Student();
        PropertyUtil.setProperty(s,"name","反射赋值");
        PropertyUtil.setProperty(s,"age",132);
        System.out.println(s.getName());
        System.out.println(s.getAge());
    }

    public static void main(String[] args) throws Exception {
        f1();
        f2();
        f3();
        f4();
        f5();
        f6();
        f7();
        f8();
        f9();
        f10();
        f11();
        f12();
        f13();
        f14();
    }
}

class PropertyUtil {
    public static void setProperty(Object obj, String field, Object value) throws Exception {
        Class<?> objClass = obj.getClass();
        Field field1 = objClass.getDeclaredField(field);
        field1.setAccessible(true);
        field1.set(obj, value);
    }
}
classname=reflect.Teacher
methodname=say

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值