Java反射

Java反射应用广泛, 能够配置 : 类的全限定名、方法和参数, 完成对象的初始化, 甚至是反射某些方法. 这样就可以大大增强Java的可配置性, Spring IoC的基本原理也是如此.
反射可以调用私有变量和私有方法

反射机制, 会先拿到目标对象的类对象, 然后通过类对象获取 “构造器对象”, 再通过构造器对象创建一个对象

获取类对象

获取类对象时, 会导致类属性被初始化; 无论什么途径获取类对象,都会导致静态属性被初始化,而且只会执行一次。(除了直接使用 Class c = A.class 这种方式,这种方式不会导致静态属性被初始化)
获取类对象的三种方式

public class A{
}
CLass cl1=Class.forName("com.test.A");
Class cl2=A.class;
class cl3=new A().getClass();

通过反射构建对象

在Java中允许通过反射配置信息构建对象,

ReflectServiceImpl类

package com.IDEA_Project.reflect;

public class ReflectServiceImpl {
    public void sayHello(String name){
        System.out.println("Hello "+name);
    }

    //通过反射去构建对象
    public ReflectServiceImpl getInstance(){
        //用反射产生一个对象, 然后将其返回
        ReflectServiceImpl object = null;
        try {
            object = (ReflectServiceImpl)Class.forName("com.IDEA_Project.reflect").newInstance();
            //给类加载器注册了一个类ReflectServiceImpl的全限定名, 然后通过newInstance方法初始化了一个类对象

			/* object = (ReflectServiceImpl)Class.forName("com.IDEA_Project.reflect.ReflectServiceImpl").getConstructor().newInstance();
             *通过上述方法也可以通过反射创建一个对象
             * 会抛出的错误: NoSuchMethodException、InvocationTargetException
             */
        }catch (ClassNotFoundException | InstantiationException | IllegalAccessException e){
            e.printStackTrace();
        }
        return object;
    }
}

上述类是无参数类, 下面来写有参数的类如何使用反射生成对象

ReflectServiceImpl2类

package com.IDEA_Project.reflect;

import java.lang.reflect.InvocationTargetException;

public class ReflectServiceImpl2 {
    private String name;
    public ReflectServiceImpl2(String name){
        this.name =name;
    }

    public void sayHello(){
        System.out.println("hello"+name);
    }

    public ReflectServiceImpl2 getInstance(){
        ReflectServiceImpl2 object = null;
        try {
            object = (ReflectServiceImpl2)Class.forName("com.IDEA_Project.reflect.ReflectServiceImpl2")
                    .getConstructor(String.class)
                    .newInstance("小王");
            /*
            先通过forname加载到类的加载器, 然后通过Constructor方法(参数可以是多个,
        此处代表有且只有一个参数类型为string的构造方法,通过这个方法可以对重名方法进行排除)
            再使用newInstance方法生成对象, 实际效果等于object = new ReflectServiceImpl2("小王");
             */
        }catch (ClassNotFoundException | InstantiationException
                | IllegalAccessException | NoSuchMethodException
                | SecurityException | IllegalArgumentException
                | InvocationTargetException e) {
            e.printStackTrace();
        }
        return object;
    }
}

反射优点 : 配置就可以生成对象, 可以解除程序的耦合度, 比较灵活.
反射缺点 : 运行比较慢

在大部分情况下为了灵活度, 降低程序的耦合度, 我们还是会使用反射 , 比如Spring IoC 容器

反射方法

还是以ReflectServiceImpl类为例

package com.IDEA_Project.reflect;

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

public class ReflectServiceImpl {
    public void sayHello(String name){
        System.out.println("Hello "+name);
    }

    //通过反射去构建对象
    public ReflectServiceImpl getInstance(){
        //用反射产生一个对象, 然后将其返回
        ReflectServiceImpl object = null;
        try {
            object = (ReflectServiceImpl)Class.forName("com.IDEA_Project.reflect.ReflectServiceImpl").newInstance();
            //给类加载器注册了一个类ReflectServiceImpl的全限定名, 然后通过newInstance方法初始化了一个类对象
        }catch (ClassNotFoundException | InstantiationException | IllegalAccessException e){
            e.printStackTrace();
        }
        return object;
    }

    public Object reflectMethod(){
        Object returnObj = null;
        ReflectServiceImpl target = new ReflectServiceImpl();
        try{
            Method method = ReflectServiceImpl.class.getMethod("sayHello", String.class);
            //第一个参数是方法名称, 第二个参数是参数类型(列表类型)多个参数可以编写多个类型, 这样就能获得反射的方法对象
            //target.getClass().getMethod("sayHello", String.class);当不知道具体实现类是哪个时, 也可以使用本行方法

            returnObj = method.invoke(target,"小王");
            //反射, 使用target对象调用方法,而小王是参数 相当于target.SayHello("小王");
            //如果有多个参数method.invoke(target,obj1,obj2,obj3,...);
        }catch (NoSuchMethodException| SecurityException
                | IllegalAccessException | IllegalArgumentException
                | InvocationTargetException e){
            e.printStackTrace();
        }
        return returnObj;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值