java的反射机制,理解一下

1,java反射是什么

首先应该先了解两个概念,编译期运行期,编译期就是编译器帮你把源代码翻译成机器能识别的代码,比如编译器把java代码编译成jvm识别的字节码文件,而运行期指的是将可执行文件交给操作系统去执行,JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制

 

2,java反射(Reflection)的底层实现原理

众所周知Java有个Object 类,是所有Java 类的继承根源,其内声明了数个应该在所有Java 类中被改写的方法:hashCode()、equals()、clone()、toString()、getClass()等。其中getClass()返回一个Class 对象

而这个Class 类十分特殊。它和一般类一样继承自Object,当一个class被加载,或当加载器(class loader)的defineClass()被JVM调用,JVM 便自动产生一个Class 对象。

而Class对象是java反射故事起源。Class类提供了大量的实例方法来获取该Class对象所对应的详细信息,这里只是做简单的介绍,详细请参考JDK文档,这边提供一个在线的中文文档:

http://tool.oschina.net/apidocs/apidoc?api=jdk-zh

这边列了下Class类其中的很少yibufen方法,

获取公共构造器 getConstructors()
获取所有构造器 getDeclaredConstructors
获取包含的方法 getMethod()
获取包含的属性 getField(String name)
获取内部类 getDeclaredClasses()
获取外部类 getDeclaringClass()
获取所实现的接口 getInterfaces()
获取修饰符 getModifiers()
获取所在包 getPackage()
获取类名包含包路径  getName()
类名不包含包路径  getSimpleName()

 

3,java反射的简单演示

上面介绍了下java反射的实现机制,接下来主要来演示一下反射的使用

首先定义一个user对象类如下:

public class User implements Serializable {    /**     *      */    private static final long serialVersionUID = 1L;    /**     * 用户id     */    private Integer userId;    /**     * 用户名称     */    private String userName;

   /**     * 公共元素     */    public String age;

   private User(Integer userId){}

   public User(){}    public User(Integer userId, String userName) {        super();        this.userId = userId;        this.userName = userName;    }    /**     * @return the userId     */    public Integer getUserId() {        return userId;    }    /**     * @param userId the userId to set     */    public void setUserId(Integer userId) {        this.userId = userId;    }    /**     * @return the userName     */    public String getUserName() {        return userName;    }    /**     * @param userName the userName to set     */    public void setUserName(String userName) {        this.userName = userName;    }

}

测试反射类:

public class Test {    public static void main(String[] args) throws ClassNotFoundException {        // 第一种方法 直接通过类名获取class (一般不会这么用,因为实例都获取到了没必要多此一举)        User user = new User();        Class class1 = user.getClass();        System.out.println("我是方法1反射处理的类 = "+class1);        System.out.println("我是方法1反射处理的类的父类 = "+class1.getSuperclass());        System.out.println("----------------------------------------------------");        // 第二种办法通过类名的方法获取class 需要增加对应的类引用        Class class2 = User.class;        System.out.println("我是方法2反射处理的类 = "+class2);        System.out.println("我是方法2反射处理的类的父类 = "+class2.getSuperclass());        System.out.println("----------------------------------------------------");        // 第三种办法通过全类名获取,用的比较多,也推荐使用这种方式        Class class3 = Class.forName ("com.zhang.reflection.User");        System.out.println("我是方法3反射处理的类 = "+class3);        System.out.println("我是方法3反射处理的类的父类 = "+class3.getSuperclass());        System.out.println("----------------------------------------------------");        // 反射获取User对象的公共构造器        Constructor<User>[] constructors = class3.getConstructors();        for(int i=0;i<constructors.length;i++){            System.out.println("我是公共构造器"+(i+1)+" = "+constructors[i]);        }        System.out.println("----------------------------------------------------");        //反射获取User对象的所有构造器        Constructor<User>[] dconstructors = class3.getDeclaredConstructors();        for(int i=0;i<dconstructors.length;i++){            System.out.println("我是所有构造器"+(i+1)+" = "+dconstructors[i]);        }        System.out.println("----------------------------------------------------");        // 反射获取User对象的 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法        Method[]  methods = class3.getMethods();        for(int i=0;i<methods.length;i++){            System.out.println("我是公共方法"+(i+1)+" = "+methods[i]);        }        System.out.println("----------------------------------------------------");        // 反射获取User对象的 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法        Method[]  dmethods = class3.getDeclaredMethods();        for(int i=0;i<dmethods.length;i++){            System.out.println("我是所有的方法"+(i+1)+" = "+dmethods[i]);        }        System.out.println("----------------------------------------------------");        // 获取包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段        Field[] fields = class3.getFields();        for(int i=0;i<fields.length;i++){            System.out.println("我是公共的field"+(i+1)+" = "+fields[i]);        }        System.out.println("----------------------------------------------------");        Field[] dfields = class3.getDeclaredFields();        for(int i=0;i<dfields.length;i++){            System.out.println("我是所有的field"+(i+1)+" = "+dfields[i]);        }        System.out.println("----------------------------------------------------");        String sname = class3.getSimpleName();        System.out.println("我是类名不包含包路径 = "+sname);        System.out.println("----------------------------------------------------");        String name = class3.getName();        System.out.println("我是类名包含包路径 = "+name);        System.out.println("----------------------------------------------------");        Package packA=class3.getPackage();        System.out.println("我是类的包路径 = "+packA.getName());        System.out.println("----------------------------------------------------");        Class<?>[] interfaces=class3.getInterfaces();        for(int i=0;i<interfaces.length;i++){            System.out.println("我是实现的接口"+(i+1)+" = "+interfaces[i]);        }        System.out.println("----------------------------------------------------");        // 返回此类或接口以整数编码的 Java 语言修饰符。修饰符由 Java 虚拟机的 public、 protected、 private、 final、 static、 abstract 和 interface 对应的常量组成;        // 它们应当使用 Modifier 类的方法来解码        Integer modefiers = class3.getModifiers();        System.out.println("我是类的modefiers = "+modefiers);    }}

4,java反射的应用场景

a,注解的使用

java注解实例的底层实现就是java反射。

b,编写基础框架

有一句话这么说来着:反射机制是很多Java框架的基石,经典的就是在xml文件或者properties里面写好了配置,然后在Java类里面解析xml或properties里面的内容,得到一个字符串,然后用反射机制,根据这个字符串获得某个类的Class实例,这样就可以动态配置一些东西,spring,Hibernate底层都有类似的实现

c,其他在编码阶段不知道那个类名,要在运行期从配置文件读取类名配置

如下:这段代码想必大家肯定都有写过,这个数据库的连接驱动类就是编译的时候不知道你到底是用的mysql,oracle还是其他数据库,而是由运行期动态加载的

// 1.加载驱动程序        Class.forName("com.mysql.jdbc.Driver");        // 2.获得数据库的连接        Connection conn = DriverManager.getConnection(URL, NAME, PASSWORD);        // 3.通过数据库的连接操作数据库,实现增删改查        Statement stmt = conn.createStatement();        ResultSet rs = stmt                .executeQuery("select user_name,age from user");        while (rs.next()) {// 如果对象中有数据,就会循环打印出来            System.out.println(rs.getString("user_name") + ","                    + rs.getInt("age"));        }

注:以上介绍了反射的应用场景,开发业务代码中应尽量少用反射,第一是代码可读性不是特别好,第二是反射需要运行期jvm去重新解析性能上也没有直接使用好,唯一比较合理的地方是业务中需要用到AOP可以大大简化业务代码建议使用

原文地址:https://www.cnblogs.com/Sky-Raining/p/10252668.html

时间: 2024-10-13 04:12:33

java的反射机制,理解一下的相关文章

深入理解java的反射机制

今天将从以下4方面来系统的学习一下java的反射机制: java反射是什么 java反射(Reflection)底层实现原理 java反射的简单演示 java反射的应用场景 1,java反射是什么 首先大家应该先了解两个概念,编译期和运行期,编译期就是编译器帮你把源代码翻译成机器能识别的代码,比如编译器把java代码编译成jvm识别的字节码文件,而运行期指的是将可执行文件交给操作系统去执行,JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够

java的反射机制

一.java的反射机制浅谈 最近研究java研究得很给力,主要以看博文为学习方式.以下是我对java的反射机制所产生的一些感悟,希望各位童鞋看到失误之处不吝指出.受到各位指教之处,如若让小生好好感动,说不定会请各位吃饭哦! 1.何谓反射机制 根据网文,java中的反射机制可以如此定义: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 2.反射

Java 类反射机制分析

一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某种机制来实现对自己行为的描述和检测,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 在Java中的反射机制,被称为Reflection.(大家看到这个单词,第一个想法应该就是去开发文档中搜一下了.)它允许运行中的Java程序对自身进行检查,并能直接操作程序的内部属性或方法.Reflection机制

学习:java原理—反射机制

一.什么是反射:反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.这一概念的提 出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩.其中 LEAD/LEAD++ .OpenC++ .MetaXa和OpenJava等就是基于反射机制的语言.最近,反射机制也被应用到了视窗系统.操作系统和文件系统中. 反射本身并不 是一个新概念,尽管计算机科学赋予了反射概念新的含义.在计算机科

Java的反射机制和动态代理

介绍Java注解的时候,多次提到了Java的反射API.与javax.lang.model不同的是,通过反射API可以获取程序在运行时刻的内部结构.反射API中提供的动态代理也是非常强大的功能,可以原生实现AOP中 的方法拦截功能.正如英文单词reflection的含义一样,使用反射API的时候就好像在看一个Java类在水中的倒影一样.知道了Java类的内部 结构之后,就可以与它进行交互,包括创建新的对象和调用对象中的方法等.这种交互方式与直接在源代码中使用的效果是相同的,但是又额外提供了运行时

java的反射机制入门

理解Java的反射机制对学习Java框架有很大帮助,比如Spring框架的核心就是使用Java反射实现的,同时对做一些Java底层操作也会有帮助,比如字节码操作.自定义注解等. 什么是反射 Java反射说的是在运行状态中,对于任何一个类,我们都能够直到这个类有哪些方法和属性.对于任何一个对象,我们都能够对它的方法和属性进行调用.这种动态获取对象信息和调用对象方法的功能就是Java的反射机制. 反射的三种方式 反射其实就是获取类的字节码文件,也就是.class文件,那么我们就可以通过Class这个

Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别(转)

一.Java的反射机制   每个Java程序执行前都必须经过编译.加载.连接.和初始化这几个阶段,后三个阶段如下图:  其中 i.加载是指将编译后的java类文件(也就是.class文件)中的二进制数据读入内存,并将其放在运行时数据区的方法区内,然后再堆区创建一个Java.lang.Class对象,用来封装类在方法区的数据结构.即加载后最终得到的是Class对象,并且更加值得注意的是:该Java.lang.Class对象是单实例的,无论这个类创建了多少个对象,他的Class对象时唯一的!!!!.

Java 中反射机制的深入研究

昨天学习了java的反射机制,今天继续深入学习一下. 一.通过反射操作数组 反射不光只能用在类中,也可用在任意的引用数据类型上.当然包括数组. 通过java.lang.reflect.Array 类 可操作数组,java.lang.reflect.Array 类 下面提供了很多方法. 例如 public static Object get(Object array,int index)throws IllegalArgumentException,ArrayIndexOutOfBoundsExc

JAVA的反射机制学习笔记(二)

上次写JAVA的反射机制学习笔记(一)的时候,还是7月22号,这些天就瞎忙活了,自己的步伐完全被打乱了~不能继续被动下去,得重新找到自己的节奏. 4.获取类的Constructor 通过反射机制得到某个类的构造器,然后调用该构造器创建该类的一个实例 Class<T>类提供了几个方法获取类的构造器. public Constructor<T> getConstructor(Class<?>... parameterTypes) 返回一个 Constructor 对象,它反

Java通过反射机制修改类中的私有属性的值

首先创建一个类包含一个私有属性: class PrivateField{ private String username = "Jason"; } 通过反射机制修改username的值: //创建一个类的对象 PrivateField privateField = new PrivateField(); //获取对象的Class Class<?> classType = privateField.getClass(); //获取指定名字的私有域 Field field =