[Java] Java反射
首先推荐三个十分有趣的网站:
http://www.programcreek.com/simple-java/
http://tutorials.jenkov.com/
http://www.meetup.com/
Java Reflection makes it possible to inspect classes, interfaces, fields and methods at runtime, without knowing the names of the classes, methods etc. at compile time. It is also possible to instantiate new objects, invoke methods and get/set field values using reflection.
Classes
From the classes you can obtain information about:
- Class Name
- Class Modifies (public, private, synchronized etc.)
- Package Info
- Superclass
- Implemented Interfaces
- Constructors
- Methods
- Fields
- Annotations
在做任何操作前,你必须获取java.lang.Class对象。Java中所有类型,包括基础类型,数组,都有关联的class对象。获取class的方式
1)如果在编译时知道类名: MyClass.class
2) 如果编译时不知道类名但是在运行时能获取字符串: Class.forName("...'') //如果在classpath中找不到,会抛出ClassNotFoundException
Class Name
String className = aClass.getName(); // 获取类全名,包括包名
String className = aClass.getSimpleName(); //不包括包名
Class Modifiers
可以通过class对象访问类的修饰符,修饰符有:public,private,static等等。
int modifiers = aClass.getModifiers(); // int 类型
Modifier.isAbstract(int modifiers); //通过Modifier.XXX查看
Package Name
Package package = aClass.getPackage();
通过Package对象可以访问package的信息。
Superclass
Class superclass = aClass.getSuperclass();
superclass对象是一个class对象。
实现接口
Class[] interfaces = aClass.getInterfaces();
如果要获得类实现的所有接口,必须得递归的遍历父节点对象
Constructors
获取constructor对象:
Constructor[] constructors = aClass.getConstructors(); //获得所有public
constructors Constructor constructor = aClass.getConstructor(new Class[]{String.class}); // 获取带一个String类型参数的public constructor //如果找不到匹配的constructor,会抛出NoSuchMethodException
获取constructor参数:
Class[] parameterTypes = constructor.getParameterTypes();
实例化constructor:
MyObject myObject = (MyObject)constructor.newInstance("constructor-arg1");
Methods
只访问public方法:
Class.getMethod(String name, Class[] parameterTypes) and Class.getMethods() 只返回 public methods。比如:
Method method = aClass.getMethod("doSomething", new Class[]{String.class});
//get method that takes a String as argument
Method method = MyObject.class.getMethod("doSomething", String.class);
Object returnValue = method.invoke(myObject, "parameter-value1"); //如果是static方法,myObject换成null
访问private方法:
调用 Class.getDeclaredMethod(String name, Class[] parameterTypes) or Class.getDeclaredMethods()方法。比如:
PrivateObject privateObject = new PrivateObject("The Private Value");
Method privateStringMethod = PrivateObject.class.
getDeclaredMethod("getPrivateString", null);
privateStringMethod.setAccessible(true);
String returnValue = (String)
privateStringMethod.invoke(privateObject, null);
By calling Method.setAcessible(true) you turn off the access checks for this particular Method instance, for reflection only.
Fields
访问public fields:
调用 Class.getField(String name) 和 Class.getFields()方法只返回public fields。
访问private fields:
需要调用 Class.getDeclaredField(String name) or Class.getDeclaredFields()方法。例如:
PrivateObject privateObject = new PrivateObject("The Private Value");
Field privateStringField = PrivateObject.class.
getDeclaredField("privateString");
privateStringField.setAccessible(true);
String fieldValue = (String) privateStringField.get(privateObject);
By calling Field.setAcessible(true) you turn off the access checks for this particular Field instance, for reflection only.
Annotations
Annotation[] annotations = aClass.getAnnotations();
注解是Java 5引入的新feature,是一种插入java代码中的comment或元数据。注解可以在编译期被与编译工具处理,或者在运行时被Java反射处理。
比如:类 TheClass 有注解 @MyAnnotation 。注解的定义类似interfaces。The @ in front of the interface marks it as an annotation。
@MyAnnotation(name="someName", value = "Hello World")
public class TheClass {
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) public @interface MyAnnotation {
public String name();
public String value();
}
上面的注解定义中有两个指令(directives) :
@Retention(RetentionPolicy.RUNTIME) means that the annotation can be accessed via reflection at runtime. If you do not set this directive, the annotation will not be preserved at runtime, and thus not available via reflection.
@Target(ElementType.TYPE) means that the annotation can only be used ontop of types (classes and interfaces typically). You can also specify METHOD or FIELD, or you can leave the target out alltogether so the annotation can be used for both classes, methods and fields.
Generics
许多论坛文章说java泛型信息在编译时会被抹掉,但是这并不完全正确。运行java泛型的情况大致可以分成两类:
- Declaring a class/interface as being parameterizable.
- Using a parameterizable class.
我们可以获取泛型函数的返回类型,参数类型,fields类型
Arrays
Working with arrays via Java Reflection is done using the java.lang.reflect.Array class.
创建Array: int[] intArray = (int[]) Array.newInstance(int.class, 3);
访问Array: This is done via theArray.get(...) and Array.set(...) methods.
获取Array的class对象:
Class stringArrayClass = String[].class;
Class intArray = Class.forName("[I"); //用于基本类型数组,类似 "I" 这种简写方式只适用于数组情况
Class stringArrayClass = Class.forName("[Ljava.lang.String;"); //用于object数组
动态代理*
You create dynamic proxies using the Proxy.newProxyInstance() method. The newProxyInstance()methods takes 3 parameters:
- The
ClassLoaderthat is to "load" the dynamic proxy class. - An array of interfaces to implement.
- An
InvocationHandlerto forward all methods calls on the proxy to.
例如:
InvocationHandler handler = new MyInvocationHandler();
MyInterface proxy = (MyInterface) Proxy.newProxyInstance(
MyInterface.class.getClassLoader(),
new Class[] { MyInterface.class },
handler);
Class Loading & reloading*
All classes in a Java application are loaded using some subclass of java.lang.ClassLoader
动态class加载:动态加载类很容易,我们只需要获得一个 ClassLoader 然后调用 loadClass()方法
public class MainClass {
public static void main(String[] args){
ClassLoader classLoader = MainClass.class.getClassLoader();
try {
Class aClass = classLoader.loadClass("com.jenkov.MyClass");
System.out.println("aClass.getName() = " + aClass.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
动态class重加载:重加载比较复杂点,因为java加载一个类会检查类是否被加载。使用java buildin classLoader不可能实现重载。要实现这点,必须自己实现classloader。
TODO
[Java] Java反射的更多相关文章
- JAVA的反射理解
1----------------------------反射的概念----------------------------------------------- JAVA的反射机制是在运行状态中,对 ...
- java的反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制. ...
- iOS运行时编程(Runtime Programming)和Java的反射机制对比
运行时进行编程,类似Java的反射.运行时编程和Java反射的对比如下: 1.相同点 都可以实现的功能:获取类信息.属性设置获取.类的动态加载(NSClassFromString(@“clas ...
- Java 类反射机制分析
Java 类反射机制分析 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某 ...
- java的反射机制
一.java的反射机制浅谈 最近研究java研究得很给力,主要以看博文为学习方式.以下是我对java的反射机制所产生的一些感悟,希望各位童鞋看到失误之处不吝指出.受到各位指教之处,如若让小生好好感动, ...
- Java:反射
初识Java反射机制: 从上面的描述可以看出Java的反射机制使得Java语言可以在运行时去认识在编译时并不了解的类/对象的信息,并且能够调用相应的方法或修改属性的值.Java反射机制的核心就是允许在 ...
- Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别
一.Java的反射机制 每个Java程序执行前都必须经过编译.加载.连接.和初始化这几个阶段,后三个阶段如下图: 其中
- java笔记--反射进阶之总结与详解
一.反射进阶之动态设置类的私有域 "封装"是Java的三大特性之一,为了能更好保证其封装性,我们往往需要将域设置成私有的, 然后通过提供相对应的set和get方法来操作这个域.但是 ...
- java笔记--反射机制之基础总结与详解
一.反射之实例化Class类的5种方式: java的数据类型可以分为两类,即引用类型和原始类型(即基本数据类型). 对于每种类型的对象,java虚拟机会实例化不可变的java.lang.Class对象 ...
- Java中反射的三种常用方式
Java中反射的三种常用方式 package com.xiaohao.test; public class Test{ public static void main(String[] args) t ...
随机推荐
- IBM云的商务动作之我见(2):IBM 和 VMware 战略合作推进混合云
本系列文章基于公开信息,对IBM云的近期商务动作比如收购.战略合作.整合等,给出本人的快速分析,仅仅代表本人个人观点,和本人所在的公司和所在的岗位没有任何关系: (1)IBM 收购 Blue Box ...
- Hibernate对象标识符
Hibernate提供的内置标识符生成器 Java语言按内存地址来识别或区分同一个类的不同对象,而关系数据库按主键来识别或区分同一个表的不同记录.Hibernate使用OID(对象标识符)来统一两者之 ...
- decode()函数
decode()函数简介: 主要作用:将查询结果翻译成其他值(即以其他形式表现出来,以下举例说明): 使用方法: Select decode(columnname,值1,翻译值1,值2,翻译值2,.. ...
- 转: Protobuf 的 proto3 与 proto2 的区别
Protobuf 的 proto3 与 proto2 的区别 On 2015-07-17 19:16:00 By Soli Protobuf 的 proto3 与 proto2 的区别 这是一 ...
- vijos P1780 【NOIP2012】 开车旅行
描述 小\(A\)和小\(B\)决定利用假期外出旅行,他们将想去的城市从\(1\)到\(N\)编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市\(i\)的海拔高度为 ...
- Python-09-线程、进程、协程、异步IO
0. 什么是线程(thread)? 线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元.一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆 ...
- BZOJ 2286 消耗战 (虚树+树形DP)
给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...
- 微信小程序之登录态维护(十一)
[未经作者本人同意,请勿以任何形式转载] >什么是登录态? 所谓登录态,就是程序在运行时,能够识别当前用户,能够证明自己的唯一性且合法. 我们知道,WEB服务器通过浏览器携带的cookie获取s ...
- Dump中查看dictionary信息的方法
In order to dump the contents of a dictionary, you need to start with either the MethodTable or the ...
- 订餐系统之微信支付,踩了官方demo的坑
最近一个项目要增加微信支付的功能,想来这个东西出来这么久了,按微信提供的应该可以很快搞定的,结果提供的demo( JS API网页支付)中各种坑,咨询他们的客服,态度倒是非常好,就是解决不了问 ...