java反射基本使用

一. 反射的作用

当程序中要定义一个不确定类型的类对象,就可以使用反射来创建类对象,因为反射只有在运行时才会被加载。

二. 反射基本使用示例

Dog类:

package com.reflect.example;

public class Dog {
    public void bark() {
        System.out.println("小狗汪汪叫");
    }
}

Demo类:

package com.reflect.example;

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

public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        String classFullPath = "com.reflect.example.Dog";
        // 加载类
        Class classDog = Class.forName(classFullPath);
        // 创建类对象
        Object dog = classDog.newInstance();
        // 获取bark方法对象
        Method method = classDog.getDeclaredMethod("bark");
        // 调用方法
        method.invoke(dog);
    }
}

三. 反射爆破

private修饰的构造器、属性、方法是不允许被访问的,反射提供了一种爆破机制,可以强制访问private修饰的构造器、属性、方法。具体操作见 (四. 反射相关类和对应方法介绍)

四. 反射相关类和对应方法介绍

1. Class

Class类是反射的核心, 每个类都有唯一的一个Class类,Class类中保存了实际类中的成员属性、成员方法、构造方法、静态变量、静态方法。

(1) 常用方法
方法作用
getName()获取全类名(带有包名的类名)
getSimpleName()获取类名
getFields() 获取所有public修饰的属性,包括父类
getDeclaredFields()获取当前类所有属性
getField(String name)根据属性名获取public属性,包括父类属性
getDeclaredField(String name)根据属性名获取本类中任意权限修饰符修饰的属性
getMethods()获取所有public方法,包括父类
getDeclaredMethods()获取本类中所有方法
getMethod(String name)根据方法名获取public方法,包括父类
getDeclaredMethod(String name)根据方法名获取本类任意权限修饰符修饰的方法
getConstructors()获取本类所有public构造方法
getDeclaredConstructors()获取本类所有权限修饰符修饰的构造方法
getConstructor(Class<?>... parameterTypes)根据参数类型获取public构造方法
getDeclaredConstructor(Class<?>... parameterTypes)根据参数类型获取所有权限修饰符修饰的构造方法
(2) 使用示例

Father类:

package com.reflect.classexample;

public class Father {
    public String name = "一个父亲";
    private int age = 30;

    public Father() {
    }

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

    public void duty() {
        System.out.println("赚钱养家");
    }

    private void attitude() {
        System.out.println("提升自己");
    }
}

Son类:

package com.reflect.classexample;

public class Son extends Father{
    public int height = 20;
    private int weight = 7;

    public Son() {
    }

    public Son(String name, int age, int height, int weight) {
        super(name, age);
        this.height = height;
        this.weight = weight;
    }

    private Son(int height, int weight) {
        this.height = height;
        this.weight = weight;
    }

    public void learn() {
        System.out.println("好好学习");
    }

    private void grow() {
        System.out.println("健康成长,养成积极向上的世界观");
    }

    public void addElectiveCourse(String cource) {
        System.out.println("选修" + cource + "课程");
    }
}

Demo类:

package com.reflect.classexample;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException {
        // 加载类
        Class classSon = Class.forName("com.reflect.classexample.Son");

        /***
         * 方法示例
         */

        // 1. 获取全类名
        System.out.println("全类名: " + classSon.getName());
        System.out.println();

        // 2. 获取类名
        System.out.println("类名: " + classSon.getSimpleName());
        System.out.println();

        // 3. 获取所有public修饰的属性,包括父类
        Field[] fields = classSon.getFields();
        for (Field field : fields) {
            System.out.println("public属性: " + field);
        }
        System.out.println();

        // 4. 获取当前类所有属性
        Field[] fields2 = classSon.getDeclaredFields();
        for (Field field : fields2) {
            System.out.println("所有属性: " + field);
        }
        System.out.println();

        // 5. 根据属性名获取public属性,包括父类属性
        Field field = classSon.getField("height");
        System.out.println(field);
        Field field2 = classSon.getField("name");
        System.out.println(field2);
        System.out.println();

        // 6.根据属性名获取本类中任意权限修饰符修饰的属性
        Field field3 = classSon.getDeclaredField("weight");
        System.out.println(field3);
        System.out.println();

        // 7. 获取所有public方法,包括父类
        Method[] methods = classSon.getMethods();
        for (Method method : methods) {
            System.out.println("public方法:" + method);
        }
        System.out.println();

        // 8. 获取本类中所有方法
        Method[] methods2 = classSon.getDeclaredMethods();
        for (Method method : methods2) {
            System.out.println("本类中方法:" + method);
        }
        System.out.println();

        // 9. 根据方法名获取public方法,包括父类
        Method dutyMethod = classSon.getMethod("duty");
        System.out.println(dutyMethod);
        Method addElectiveCourceMethod = classSon.getMethod("addElectiveCourse", String.class);
        System.out.println(addElectiveCourceMethod);
        System.out.println();

        // 10. 根据方法名获取本类任意权限修饰符修饰的方法
        Method growMethod = classSon.getDeclaredMethod("grow");
        System.out.println(growMethod);
        Method learnMethod = classSon.getDeclaredMethod("learn");
        System.out.println(learnMethod);
        System.out.println();

        // 11. 获取本类所有public构造方法
        Constructor[] constructors = classSon.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println("public构造方法:" + constructor);
        }
        System.out.println();

        // 12. 获取本类所有权限修饰符修饰的构造方法
        Constructor[] declaredConstructors = classSon.getDeclaredConstructors();
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println("所有构造方法:" + declaredConstructor);
        }
        System.out.println();

        // 13. 根据参数类型获取public构造方法
        Constructor constructor = classSon.getConstructor();
        System.out.println("public构造方法:" + constructor);
        Constructor constructor2 = classSon.getConstructor(String.class, int.class, int.class, int.class);
        System.out.println("public构造方法:" + constructor2);
        System.out.println();

        //14. 根据参数类型获取所有权限修饰符修饰的构造方法
        Constructor declaredConstructor = classSon.getDeclaredConstructor(int.class, int.class);
        System.out.println("所有权限修饰符修饰的构造方法:" + declaredConstructor);
        Constructor declaredConstructor2 = classSon.getDeclaredConstructor();
        System.out.println("所有权限修饰符修饰的构造方法:" + declaredConstructor2);
        System.out.println();
    }
}

2. Field

(1) 常用方法
方法作用
get(Object obj)获取obj对象的属性值,静态属性obj可以为nul
set(Object obj, Object value)为obj对象属性赋值为value,静态属性obj可以为null
setAccessible(booleab flag)设置是否允许访问private属性,true表示允许,false表示不允许
getType()获取属性类型
(2) 使用示例

Person类:

package com.reflect.fieldexample;

public class Person {
    public int numOfEye = 2;
    private double money = 1;

    public Person() {
    }

    public Person(int numOfEye, double money) {
        this.numOfEye = numOfEye;
        this.money = money;
    }
}

AsianPerson类:

package com.reflect.fieldexample;

public class AsianPerson extends Person{
    private float height = 170;
    public float weight = 134;

    private static int IQ = 200;

    public AsianPerson() {
    }

    public AsianPerson(int numOfEye, double money, float height, float weight) {
        super(numOfEye, money);
        this.height = height;
        this.weight = weight;
    }
}

Demo类:

package com.reflect.fieldexample;

import java.lang.reflect.Field;

public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        // 加载类
        Class<?> classAsianPerson = Class.forName("com.reflect.fieldexample.AsianPerson");
        // 创建类实例
        Object person = classAsianPerson.newInstance();

        // 获取public属性对象
        Field field = classAsianPerson.getField("weight");
        System.out.println("修改前weight:" + field.get(person));
        field.set(person, 120);
        System.out.println("修改后weight:" + field.get(person));
        System.out.println();

        // 获取属性类型
        System.out.println("weight变量类型:" + field.getType());
        System.out.println();

        // 获取private属性对象
        Field field2 = classAsianPerson.getDeclaredField("height");
        // 设置允许访问field2
        field2.setAccessible(true);
        System.out.println("修改前height:" + field2.get(person));
        field2.set(person, 175);
        System.out.println("修改后height:" + field2.get(person));
        System.out.println();

        // 获取静态属性对象
        Field field3 = classAsianPerson.getDeclaredField("IQ");
        // 设置允许访问field3
        field3.setAccessible(true);
        System.out.println("修改前IQ:" + field3.get(person));
        field3.set(person, 201);
        System.out.println("修改后IQ:" + field3.get(person));
        // 静态属性可以使用null
        field3.set(null, 250);
        System.out.println("修改后IQ:" + field3.get(null));
        System.out.println();
    }
}

3. Method

(1) 常用方法
方法作用
invoke(Object obj, Object... args)通过obj对象传入args参数调用方法,静态方法obj可以为null
getParameterTypes()获取方法参数类型
setAccessible(boolean flag)设置是否可以访问private方法, true表示允许访问,false表示不允许访问
(2) 使用示例

Phone类:

package com.reflect.methodexample;

public class Phone {
    public void call(String phoneNumber) {
        System.out.println("拨打电话" + phoneNumber);
    }
    private void fixedPosition() {
        System.out.println("移动不方便,通常放在固定地点");
    }
}

MobilePhone类:

package com.reflect.methodexample;

public class MobilePhone extends Phone{
    public void listenMusic(String name) {
        System.out.println("播放音乐<" + name + ">");
    }

    private void movedPosition() {
        System.out.println("携带方便,随时随地可以使用");
    }

    private static void sendMessage() {
        System.out.println("发短信");
    }
}

Demo类:

package com.reflect.methodexample;


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

public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class classMobilePhone = Class.forName("com.reflect.methodexample.MobilePhone");
        Object phone = classMobilePhone.newInstance();

        // 获取public方法
        Method method = classMobilePhone.getMethod("listenMusic", String.class);
        // 调用方法
        method.invoke(phone, "男儿当自强");
        Method method2 = classMobilePhone.getMethod("call", String.class);
        method2.invoke(phone, "11111111");

        // 获取方法参数类型
        Class<?>[] parameterTypes = method2.getParameterTypes();
        for (Class<?> parameterType : parameterTypes) {
            System.out.println("参数类型:" + parameterType);
        }

        // 获取private方法
        Method method3 = classMobilePhone.getDeclaredMethod("movedPosition");
        // 设置可以访问private方法
        method3.setAccessible(true);
        method3.invoke(phone);
        Method method4 = classMobilePhone.getDeclaredMethod("sendMessage");
        method4.setAccessible(true);
        method4.invoke(phone);
        method4.invoke(null);
    }
}

4. Constructor

(1) 常用方法
方法作用
newInstance(Object... initArgs)根据参数调用构造器实例化对象
getParameterTypes()获取构造器参数类型
setAccessible(boolean flag)设置是否可以访问构造器,flag为true表示允许访问,flag为false表示不允许访问
(2) 使用示例

Apple类:

package com.reflect.construtorexample;

public class Apple {
    public double price = 10;
    public String name = "苹果";

    public Apple() {
    }

    private Apple(double price) {
        this.price = price;
    }

    public Apple(double price, String name) {
        this.price = price;
        this.name = name;
    }

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

Demo类:

package com.reflect.construtorexample;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<?> classApple = Class.forName("com.reflect.construtorexample.Apple");

        // 获取无参构造
        Constructor<?> declaredConstructor = classApple.getDeclaredConstructor();
        Object apple = declaredConstructor.newInstance();
        System.out.println(apple);

        // 获取public构造
        Constructor<?> declaredConstructor2 = classApple.getDeclaredConstructor(double.class, String.class);
        Object apple2 = declaredConstructor2.newInstance(14, "黄元帅");
        System.out.println(apple2);

        // 获取参数列表
        Class<?>[] parameterTypes = declaredConstructor2.getParameterTypes();
        for (Class<?> parameterType : parameterTypes) {
            System.out.println("\t\t参数类型:" + parameterType);
        }

        // 获取private构造
        Constructor<?> declaredConstructor3 = classApple.getDeclaredConstructor(double.class);
        // 设置可以访问构造器
        declaredConstructor3.setAccessible(true);
        Object apple3 = declaredConstructor3.newInstance(19);
        System.out.println(apple3);
    }
}

有错误欢迎指出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值