Java反射

Java反射

在java的面向对象编程过程中,通常我们需要先知道一个Class类,然后new 类名()方式来获取该类的对象。也就是说我们需要在写代码的时候 (编译期或者类加载之前)就知道我们要实例化哪一个类,运行哪一个方法,这种通常被称为 静态的类加载

那么有没有一种方法 在运行期动态的改变程序的调用行为的方法 呢?

这就是要为大家介绍的“java反射机制“。

反射机制

  1. 反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息(比如成员变量,构造器,成员方法等等),并能操作对象的属性及方法。反射在设计模式和框架底层都会用到
  2. 加载完类之后,在堆中就产生了一个Class类型的对象(一个类只有一个Class对象) ,这个对象包含了类的完整结构信息。通过这个对象得到类的结构。这个对象就像面镜子,透过这个镜子看到类的结构,所以,形象的称之为: 反射

 Java反射机制原理示意图

 Java反射机制可以完成

  1. 在运行时判断任意一个对象所属的类
  2. 在运行时构造任意一个类的对象
  3. 在运行时得到任意一个类所具有的成员变量和方法
  4. 在运行时调用任意一个对象的成员变量和方法
  5. 生成动态代理

 反射相关的主要类

  1. java.lang.Class:代表个类,Class对象表示某 个类加载后在堆中的对象
  2. java.lang.reflect.Method:代表类的方法,Method对象表示某个类的方法
  3. java.lang.reflect.Field:代表类的成员变量,Field对象表示某个类的成员变量
  4. java.lang.reflect.Constructor:代表类的构造方法,Constructor对象表示构造器

这些类在java.lang.reflection

反射优点和缺点

  1. 优点:可以动态的创建和使用对象(也是框架底层核心),使用灵活,没有反射机制,框架技术就失去底层支撑。
  2. 缺点:使用反射基本是解释执行,对执行速度有影响.

反射调用优化-关闭访问检查

  1. Method和Field、 Constructor对象都有setAccessible0方法
  2. setAccessible作用是启动和禁用访问安全检查的开关
  3. 参数值为true表示反射的对象在使用时取消访问检查,提高反射的效率。参数值为false则表示反射的对象执行访问检查
     

通过反射创建对象

  1. 方式一:调用类中的public修饰的无参构造器
  2. 方式二:调用类中的指定构造器
  3. Class类相关方法
    newInstance :调用类中的无参构造器,获取对应类的对象
    getConstructor(Cas…clazz):根据参数列表,获取对应的构造器对象
    getDecalaredConstructor(Cas…clazz):根据参数列表,获取对应的构造器对象
  4. Constructor类相关方法
    setAccessible:暴破 //暴破[暴力破解],使用反射可以访间private构造器
    newlnstance(Object…obj):调用构造器

通过反射访问类中的成员

访问属性

  1. 根据属性名获取Field对象
    Field f = clazz对象.getDeclaredField(属性名);
  2. 暴破: f.setAccessible(true); //f是Field
  3. 访问
    f.set(o,值);
    syso(f.get(o));
  4. 如果是静态属性,则set和get中的参数o, 可以写成null

访问方法

  1. 根据方法名和参数列表获取Method方法对象:
  2. Method m =clazz.getDeclaredMethod(方法名,XX.class); //得到本类的所有方法
  3. 获取对象: Object o= clazz.newInstance();
  4. 暴破: m.setAacessible(true);
  5. 访问: Object returnValue = m.invoke(o,实参列表);
  6. 注意:如果是静态方法,则invoke的参数o,可以写成null!
     

反射的使用

获取Class对象的三种方式

  1.  Object ——> getClass();
  2.  任何数据类型(包括基本数据类型)都有一个“静态”的class属性
  3. 通过Class类的静态方法:forName(String  className)(常用)

 反射的书写步骤

创建dao包,接口,类

public class BookDaoImpl implements BookDao {
    @Override
    public void add() {
        System.out.println("BookDaoImpl...add");
    }
}
public interface BookDao {
    public void add();
}

创建service包,接口,类

public class BookServiceImpl implements BookService {
    public String name;
    int age;
    protected String sex;
    private String address;
 
    public BookServiceImpl(){
    }
 
    public BookServiceImpl(String name){
        this.name = name;
    }
 
    private BookServiceImpl(String name,int age,String sex,String address){
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.address = address;
    }
 
 
    BookDao bookDao = new BookDaoImpl();
    @Override
    public void add() {
        System.out.println("BookSeiviceImpl...add");
        bookDao.add();
    }
 
    @Override
    public void fun() {
        System.out.println("BookSeiviceImpl...fun");
    }
}
public class BoookServiceVip implements BookService {
    BookDao bookDao = new BookDaoImpl();
    @Override
    public void add() {
        System.out.println("BoookServiceVip...add");
    }
 
    @Override
    public void fun() {
        System.out.println("BoookServiceVip...fun");
    }
}
public interface BookService {
    public void add();
 
    public void fun();
}

创建servlet包,接口,类,测试类

public class BookServlet {
    BookService bookService = new BoookServiceVip();
    @Test
    public void add(){
        System.out.println("BookServlet.add");
        bookService.add();
    }
}
public class Test01 {
    public static void main(String[] args) throws Exception {
        Class cla = Class.forName("com.gao.service.impl.BookServiceImpl");
 
        Field[] fields = cla.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("---------");
 
        Field[] fields1 = cla.getDeclaredFields();
        for (Field field : fields1) {
            System.out.println(field);
        }
        System.out.println("===========");
 
        Constructor[] constructors = cla.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        System.out.println("-------------");
        Constructor[] constructors1 = cla.getDeclaredConstructors();
        for (Constructor constructor : constructors1) {
            System.out.println(constructor);
        }
 
        System.out.println("======================");
        Method[] methods = cla.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("-------------");
        Method[] methods1 = cla.getDeclaredMethods();
        for (Method method : methods1) {
            System.out.println(method);
        }
    }
}
public class Test02 {
    public static void main(String[] args) throws Exception {
        //读取配置文件,获取内容
//        File file=new File("D:\\code\\IdeaProjects\\spring2105\\spring01\\src\\info.properties");
//        InputStream stream=new FileInputStream(file);
        InputStream stream = Test02.class.getClassLoader().getResourceAsStream("info.properties");
 
        Properties p=new Properties();
        p.load(stream);
        String className=p.getProperty("className");
 
        //1.通过全类名获取类的Class对象
        Class cla = Class.forName(className);
        //2.通过Class对象获取类的无参构造器
        Constructor constructor = cla.getDeclaredConstructor();
        //3.使用构造器创建对象
        BookService bookService = (BookService) constructor.newInstance();
        //4.使用对象调用方法
        bookService.add();
    }
}
public class Test03 {
    public static void main(String[] args) throws Exception {
        //读取配置文件,获取内容
//        File file=new File("D:\\code\\IdeaProjects\\spring2105\\spring01\\src\\info.properties");
//        InputStream stream=new FileInputStream(file);
        InputStream stream = Test03.class.getClassLoader().getResourceAsStream("info.properties");
 
        Properties p=new Properties();
        p.load(stream);
        String className=p.getProperty("className");
        String methodName=p.getProperty("methodName");
 
        //1.通过全类名获取类的Class对象
        Class cla = Class.forName(className);
        //2.通过Class对象获取类的无参构造器
        Constructor constructor = cla.getDeclaredConstructor();
        //3.使用构造器创建对象
        BookService bookService = (BookService) constructor.newInstance();
        //4.获取方法名
        Method method = cla.getDeclaredMethod(methodName);
        //5.执行方法
        method.invoke(bookService);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值