码迷,mamicode.com
首页 > 编程语言 > 详细

【thinking in java】反射

时间:2018-10-15 14:57:20      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:thinking   cep   tor   硬盘   类型   com   new   程序   包含   

前言

反射是框架设计的灵魂,使用的前提条件:必须先得到字节码的Class,Class类用于表示字节码,字节码即是.class文件

概述

JAVA反射机制:在程序运行的过程中,对于任意一个类,都可以知道这个类的所有信息,比如:成员变量、方法、构造方法、包等信息;要想用反射机制,首先要获取到

该类的字节码文件对象Class,然后用Class类中的方法把各种成分映射成Java对象,关于.class文件,在我们new对象的时候,本地IDE自动编译,然后jvm会自动的从硬盘

读取到.class文件,并创建一个该类的Class文件,但是,如果我们new了多个该类的实例,内存中只会有一份该类的字节码文件。

API

Class 类与 java.lang.reflect 类库一起对反射的概念进行了支持,该类库包含了 Field、Method、Constructor 类 (每个类都实现了 Member 接口)该接口反映单个成员(字段

或方法)或构造方法的标识信息,正因为实现了该接口,因此可以反射相关变量、方法信息,这些类型的对象时由 JVM 在运行时创建的,用以表示未知类里对应的成员。

反射

获取字节码

在 Java 中可以通过三种方法获取类的字节码 (Class) 对象,如下:

技术分享图片
package com.oxygen.bean;

public class ReflectTest {
    public static void main(String[] args) throws ClassNotFoundException {
        Student student = new Student();
        Class<?> clazz1 = student.getClass(); //方式1
        Class<?> clazz2 = Student.class; //方式2
        Class clazz3 = Class.forName("com.oxygen.student");//方式3
    }
}
View Code

获取类信息

Student类如下

技术分享图片View Code

1. 通过构造函数对象Constructor创建对应类的实例

技术分享图片
package com.oxygen.bean;

import java.lang.reflect.Constructor;

public class ReflectTest {
    public static void main(String[] args) throws Exception {
        Student student = new Student(); //Student的带参构造函数依赖另外一个类Car
        Class<?> clazz1 = student.getClass(); //方式1
        func1(clazz1); //通过无参构造函数反射Student实例
        func2(clazz1);//通过有参构造函数反射Student实例
        func3(clazz1);//获取所有的构造函数反射Student实例
        func4(clazz1); // 反射私有构造函数
    }

    private static void func4(Class<?> clazz1) throws Exception {
        Constructor<?> declaredConstructor = clazz1.getDeclaredConstructor(String.class);
        declaredConstructor.setAccessible(true);//设置为可以访问
        System.out.println(declaredConstructor.newInstance("zhangsan"));
    }

    private static void func3(Class<?> clazz1) throws Exception {
        Constructor<?>[] constructors = clazz1.getDeclaredConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println("func3: " + constructor);
        }
    }

    /**
     * 因为Student的带参构造函数依赖另外一个类Car,因为必须保证JVM能获取到Car的字节码
     * @param clazz1
     * @throws Exception
     */
    public static void func2(Class<?> clazz1) throws Exception {
        Car car = new Car();//保证
        Constructor<?> constructor = clazz1.getConstructor(String.class, Integer.class, Car.class);
        Student student = (Student) constructor.newInstance("张三", 18, new Car());
        System.out.println(student);
    }

    public static void func1(Class<?> clazz1) throws Exception {
        Constructor<?> constructor = clazz1.getConstructor();
        Student student = (Student) constructor.newInstance();
        System.out.println(student);
    }
}
View Code

2. 获取成员方法

技术分享图片
package com.oxygen.bean;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class ReflectTest {
    public static void main(String[] args) throws Exception {
        Student student = new Student();
        Class<?> clazz1 = student.getClass();
        m1(clazz1);
        m2(clazz1);
        m3(clazz1);
        m4(clazz1);
    }

    /**
     * 获取所有的方法,包括私有的,不包括继承Object类的9个方法
     * @param clazz1
     */
    public static void m4(Class<?> clazz1) {
        Method[] declaredMethods = clazz1.getDeclaredMethods();
    }

    /**
     * 获取所有的”公有“方法,包括继承Object类的9个方法
     * @param clazz1
     */
    public static void m3(Class<?> clazz1) {
        Method[] methods = clazz1.getMethods();
    }

    /**
     * 获取私有的show4()方法
     * @param clazz1
     * @throws Exception
     */
    public static void m2(Class<?> clazz1) throws Exception {
        Method method;
        method = clazz1.getDeclaredMethod("show4", int.class);
        Student stu = func1(clazz1); // 实例化一个Student对象
        method.setAccessible(true);
        method.invoke(stu, 20);//反射私有方法show4(),第一个参数是实例,第二个参数是被反射方法的参数
    }

    /**
     * 获取公有的show1()方法
     * @param clazz1
     * @throws Exception
     */
    public static void m1(Class<?> clazz1) throws Exception {
        Method method = clazz1.getMethod("show1", String.class); //第一个参数是方法名称,第二个参数是形参类型
        Student stu = func1(clazz1); // 实例化一个Student对象
        method.invoke(stu, "lisi"); //反射公有方法show1(),第一个参数是实例,第二个参数是被反射方法的参数
    }

    public static Student func1(Class<?> clazz1) throws Exception {
        Constructor<?> constructor = clazz1.getConstructor();
        Student student = (Student) constructor.newInstance();
        return student;
    }
}
View Code

【thinking in java】反射

标签:thinking   cep   tor   硬盘   类型   com   new   程序   包含   

原文地址:https://www.cnblogs.com/oxygenG/p/9789946.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!