java反射的实战教程(简单且高效)

1. 参考

建议按顺序阅读以下文章
学了这么久的java反射机制,你知道class.forName和classloader的区别吗?
Java反射(超详细!)

2. 实战

2.1 通过Class.forName()方法获取字节码
这个方法会去我们的操作系统寻找这个class文件(java编译生成的字节码文件),并将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。注意这里的静态块指的是在类初始化时的一些数据。

public class User {
    private static int a = 10;
    {
        System.out.println("普通代码块");
    }
    static{
        System.out.println("静态变量a:"+a);
        System.out.println("静态代码块");
    }
}

// 测试
public class FDDTest {
    public static void main(String[] args) {
        try {
            Class forNameUser = Class.forName("com.fdd.reflect.User");
            System.out.println("Class.forName testing...");
            System.out.println("user " + forNameUser.getName());
        } catch (ClassNotFoundException e){
            e.printStackTrace();
        }
    }   
}

/** 
	静态变量a:10
	静态代码块
	Class.forName testing...
	user com.fdd.reflect.User
*/

2.2 创建对象。

class ReflectTest02{
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        // 通过反射机制,获取Class,通过Class来实例化对象
        Class c = Class.forName("javase.reflectBean.User");
        // newInstance() 这个方法会调用User这个类的无参数构造方法,完成对象的创建。
        // 重点是:newInstance()调用的是无参构造,必须保证无参构造是存在的!
        Object obj = c.newInstance();
        System.out.println(obj);
    }
}

2.3 获取并调用属性Field

class ReflectFieldQuery{
    public static void main(String[] args) throws ClassNotFoundException {
		// 反射机制创建对象
        Class studentClass = Class.forName("javase.reflectBean.Student");
        //获取所有的属性
        Field[] fields = studentClass.getDeclaredFields();
        for (Field f : fields){
        	// 获取属性的修饰符列表,返回的修饰符是一个数字,每个数字是修饰符的代号
            // 用Modifier类的toString转换成字符串
        	String modifiers = Modifier.toString(f.getModifiers());
          	// 获取属性的类型
          	String typeName = f.getType().getSimpleName();
          	// 获取属性的名字
         	String fieldName = f.getName();
        }
    }
}

class ReflectFieldUpdate{
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //使用反射机制给属性赋值
        Class studentClass = Class.forName("javase.reflectBean.Student");
        Object obj = studentClass.newInstance();
        Field nameField = studentClass.getDeclaredField("name");
      	
      	// 打破封装(反射机制的缺点:打破封装,可能会给不法分子留下机会!!!)
        // 这样设置完之后,在外部也是可以访问private的。
        nameField.setAccessible(true);
        nameField.set(obj, "liming");
        System.out.println(nameField.get(obj));
    }

2.4 获取并调用方法Method

class ReflectMethodQuery{
    public static void main(String[] args) throws ClassNotFoundException {
        Class userServiceClass = Class.forName("java.lang.String");

        // 获取所有的Method(包括私有的!)
        Method[] methods = userServiceClass.getDeclaredMethods();
        for (Method m : methods){
            String modifiers = Modifier.toString(m.getModifiers());
            String returnTypeName = m.getReturnType().getSimpleName();
            String methodName = m.getName();
            Class[] parameterTypes = m.getParameterTypes();
        }
    }
}

// 重点:必须掌握,通过反射机制怎么调用一个对象的方法?五颗星*****
class ReflectMethodInvoke{
    public static void main(String[] args) throws Exception {
        //使用反射机制调用方法
        Class userServiceClass = Class.forName("javase.reflectBean.UserService");
        // 创建对象
        Object obj = userServiceClass.newInstance();
        // 获取Method
        Method loginMethod = userServiceClass.getDeclaredMethod("login", String.class, String.class);
        Object resValues = loginMethod.invoke(obj, "admin", "123");//注:方法返回值是void 结果是null
        System.out.println(resValues);
    }
}

2.5 获取并调用构造器Constructor

class ReflectConstructorQuery{
    public static void main(String[] args) throws ClassNotFoundException {

        Class vipClass = Class.forName("javase.reflectBean.Vip");
        Constructor[] constructors = vipClass.getDeclaredConstructors();
        for (Constructor c : constructors){
            String modifiers = Modifier.toString(c.getModifiers());
            String returnTypeName = c.getReturnType().getSimpleName();
            String methodName = c.getName();
            Class[] parameterTypes = c.getParameterTypes();
        }
    }
}

class ReflectConstructorInvoke{
    public static void main(String[] args) throws Exception {
        Class vipClass = Class.forName("javase.reflectBean.Vip");
        // 调用无参数构造方法
        Object obj1 = vipClass.newInstance();//Class类的newInstance方法
        Constructor c1 = vipClass.getDeclaredConstructor(int.class, String.class, String.class, boolean.class);
        Object obj2 = c1.newInstance(321, "lsi", "1999-10-11", true);
        System.out.println(obj2);

        // 获取无参数构造方法
        Constructor c2 = vipClass.getDeclaredConstructor();
        Object obj3 = c2.newInstance();
        System.out.println(obj3);
    }
}

附录

Class类方法
在这里插入图片描述
Field类方法
在这里插入图片描述
在这里插入图片描述
Method类方法
在这里插入图片描述
Constructor类方法
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值