先推荐安装一个 eclipse 的反编译插件  Enhanced Class Decompiler

是什么?

在说反射之前先说一下编译时类型和运行时类型,大家都知道List是一个接口,它是不可以被实例化的,但是可以通过多态实现:List list = new ArrayList(); 对于变量list来说编译时期他被声明为List类型,但是真正使用的确实ArrayList中的成员(在堆中创建的是ArrayList的对象),所以list的运行时类型是ArrayList,它的运行时类就是ArrayList被编译之后加载到内存的字节码类文件。

再说反射,反射是java中一种可以在执行期间获取类内部信息的技术,说白一点就是根据加载的类字节码文件去获取类本身的一种技术,之前介绍了类加载,加载过程中会创建一个Class类的对象来表示这个类,每一个Class类的对象都是一个运行时类,所以反射就是根据运行时类获取其本类信息并使用这个类的一种技术,反射号称是java实现动态编程的关键。为什么说反射是实现动态编程的关键呢?我自己的理解是这样的:假设我写了一个方法用于处理很多类,这个时候呢,我不可能为每一个类都写一个方法,可是呢,我知道每一个运行时类都是Class的对象,并且我可以根据class对象获取其本类的对象,所以这个时候,我接受的参数就可以是一个Class类型的参数,这样就使得代码可以高度复用了,这就是反射的魅力。通过使用反射,可以使得代码高度复用,大大的降低代码的耦合性。

有什么用?

具体说一下反射的能力:使用反射可以在运行时判断任意一个对象所属的类、构造一个类的对象、判断一个类具有的成员变量和方法、用一个对象的成员变量和方法等等。通过使用反射可以通过运行时类去操作类本身的所有属性。

怎么用?

想要使用反射,就要获取运行时类,那么运行时类如何获取和表示呢?在java中每一个运行时类都是java.lang.Class的对象,所以可以使用Class来声明运行时类,而获取运行时类的方式有四种,代码如下:

public static void main(String[] args) {//1、通过类的.class属性Class<User> c1 = User.class;//2、通过类对象的.getClass方法User user = new User();Class c2 = user.getClass();//3、通过Class类的forName方法,一般用这个try {Class c3 = Class.forName("com.czp.reflection.User");} catch (ClassNotFoundException e) {e.printStackTrace();}//4、通过类的加载器获取(这种一般用的不多)try {Class<?> c4 = ClassLoader.getSystemClassLoader().loadClass("com.czp.reflection.User");} catch (ClassNotFoundException e) {e.printStackTrace();}
}

这里需要说明的一点是,在一个进程中,一个类的字节码文件添加到内存中后就是一个运行时类,每个运行时类只会加载一次。

获取了运行时类也就是Class的对象之后可以做些什么呢?如何利用反射?下边具体说一下

获取类的构造方法、创建类的对象:

public class ReflectionTest {public static void main(String[] args) {ReflectionTest test = new ReflectionTest();test.getClassConstructors();}//获取User的运行时类
@SuppressWarnings("unchecked")
public Class<User> getUser()
{String name = "com.czp.reflection.User";Class<User> user= null;try {user = (Class<User>) Class.forName(name);} catch (ClassNotFoundException e) {e.printStackTrace();}return user;
}
//测试获取类中的构造方法,创建类的实例
public void getClassConstructors()
{try{Class<User> userClass = getUser();//1、直接调用Class中方法创建类的对象,这种方法的前提是类中必须要有一个公共的无参构造方法User user = userClass.newInstance();//2、通过类中对应的构造方法创建对象// 首先就需要先获取这个类中的构造方法//Declared 有声明之意,可理解为只要是声明的构造方法都可以获取到,获取所有构造方法(不管权限如何)Constructor<?>[] declaredConstructors = userClass.getDeclaredConstructors();//只能获取所有公共的构造方法Constructor<?>[] constructors = userClass.getConstructors();//获取指定参数的构造方法(所有的)Constructor<User> declaredConstructor = userClass.getDeclaredConstructor(String.class);//如果构造方法是私有的,通过setAccessible(true)设置可以使用私有构造方法进行创建对象declaredConstructor.setAccessible(true);User privateUser = declaredConstructor.newInstance("zhangsan");//User [name=zhangsan, age=null]System.out.println(privateUser);//获取指定参数的构造方法(共有的)Constructor<User> constructor = userClass.getConstructor(Integer.class);//再根据构造方法创建类的对象User user2 = constructor.newInstance(5);//User [name=null, age=5]}catch (Exception e) {e.printStackTrace();}
}
}

获取运行时类的成员:

//测试获取类中的成员信息
public void getClassMethods() {try{Class<User> userClass = getUser();User user = userClass.newInstance();//---------------------------处理方法----------------------////1、获取所有的方法Method[] declaredMethods = userClass.getDeclaredMethods();//2、根据方法的名称参数获取方法Method declaredMethod = userClass.getDeclaredMethod("show");//使用方法,如果是私有方法则先强制设置以下declaredMethod.setAccessible(true);declaredMethod.invoke(user, null);//3、获取所有公共的方法(包括父类的)Method[] methods = userClass.getMethods();//4、获取方法,不写了,就是根据名字获取,和上边一样//---------------------------处理变量----------------------////1、获取所有变量Field[] declaredFields = userClass.getDeclaredFields();//2、获取指定变量Field declaredField = userClass.getDeclaredField("name");declaredField.setAccessible(true);declaredField.set(user, "zhangsan");System.out.println(declaredField.get(user));//zhangsan//3、还有两个获取所有共有的变量}catch (Exception e) {e.printStackTrace();}
}

获取运行时类的其他:

public void getClassOther(){try{Class<User> userClass = getUser();User user = userClass.newInstance();//1、可以获取注解Annotation[] declaredAnnotations = userClass.getDeclaredAnnotations();//2、所在包名Package p = userClass.getPackage();//3、获取父类Class<? super User> superclass = userClass.getSuperclass();//4、获取实现的接口Class<?>[] interfaces = userClass.getInterfaces();//还有其他,查看API}catch (Exception e) {e.printStackTrace();}
}

21、java中的反射机制相关推荐

  1. 浅说Java中的反射机制(一)

    在学习传智播客李勇老师的JDBC系列时,会出现反射的概念,由于又是第一次见,不免感到陌生.所以再次在博客园找到一篇文章,先记录如下: 引用自java中的反射机制,作者bingoideas.(()为我手 ...

  2. 【Java面试题】21 Java中的异常处理机制的简单原理和应用。

    [Java面试题]21 Java中的异常处理机制的简单原理和应用. 参考文章: (1)[Java面试题]21 Java中的异常处理机制的简单原理和应用. (2)https://www.cnblogs. ...

  3. java代码安全检测机制_全面解析:java中的反射机制,内含代码验证解析

    什么是反射? 在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功 ...

  4. formdata 接受参数中带有class 对象_浅析JAVA中的反射机制及对Servlet的优化

    今天来聊聊java中的反射机制,工作以后发现很多东西动不动就要使用反射或者动态代理,如果不能很好的理解反射,那么对于动态代理等一些重要的设计模式就会有种不够通透的感觉. 所谓的反射,就是在运行状态中, ...

  5. java中的反射机制是什么

    给大家介绍一下java中的反射机制,java中反射机制更体现出了java的灵活性.多态.和类之间的耦合性. 1:反射是一种间接操作目标对象的机制,只要给定类的名字,就可以通过反设机制获取所有的类信息. ...

  6. Java中的反射机制详讲

    Java中的反射机制详讲 1.反射机制_介绍_Class对象获取 2.反射机制_动态操作_构造器_方法_属性 3.动态编译_DanamicCompile_反射调用main方法问题 好文推荐:排序.查找 ...

  7. 【反射机制】Java中的反射机制,使用反射机制创建对象、访问属性、方法、构造方法等

    这篇文章主要是整理了Java中的反射机制,包括:反射机制概念.反射机制访问构造方法.反射机制访问普通方法.反射机制访问属性,反射机制访问修饰符. 目录 一.反射机制概念 二.反射机制使用 (1)加载C ...

  8. JAVA基础--JAVA中的反射机制详解

    JAVA反射机制     JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能 ...

  9. 根据实例详解Java中的反射机制

    概念: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java ...

  10. 黑马程序员,黑马论坛 ------JAVA中的反射机制

    文章来源:黑马程序员,黑马论坛 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法 ...

最新文章

  1. 6-6.用HLSL定义点光源
  2. NSThread Run Loop
  3. 洛谷P1373 小a和uim之大逃离
  4. 深入SpringBoot:自定义Endpoint
  5. layui富文本编译器添加图片
  6. 第六章 hbase shell 命令
  7. 【BZOJ1899】[Zjoi2004]Lunch 午餐 贪心+DP
  8. java secondtotime_Java中的LocalTime toSecondOfDay()方法
  9. 前端 JS 之 AJAX 简介及使用
  10. 汇编笔记-DOSBox安装和使用
  11. [Swift]SwiftyJSON的使用:解析JSON
  12. 特效字幕(ass)简易制作教程
  13. 疯狂java讲义第6版_疯狂java讲义第6版
  14. 以图搜图 图像匹配_基于内容的图像检索(CBIR) ——以图搜图
  15. kdc服务器密码修改,kerberos之kdc主备
  16. 诺维信和科汉森合并获股东批准,将共同创建一家世界一流的发酵公司
  17. 会火吗?苹果软件新专利:用户自拍照可组成合影
  18. android 渐变的背景色,Android背景渐变xml
  19. 若某非空二叉树的先序序列和后序序列正好相反,或者正好相同,则二叉树形态是怎么样的?
  20. mac安装配置zsh

热门文章

  1. 微型计算机硬件采用什么,微型计算机的硬件系统包括什么?
  2. aop springboot 传入参数_Springboot添加AOP打印请求参数
  3. python——学习笔记3
  4. com.mysql.cj.exceptions.InvalidConnectionAttributeException
  5. hdu2648 Shopping-map容器
  6. C++map容器-大小和互换
  7. 数据结构与算法--重建二叉树
  8. 分析股票大数据_Python大数据分析量学祖师爷网站数据
  9. 类欧几里得算法详细推导过程(附带模板)
  10. LOJ#2145. 「SHOI2017」分手是祝愿