java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台(即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称。
本文主要介绍了 Java 中反射的相关知识。具有很好的参考价值,下面跟着小编一起来看下吧
阅读目录
Java 反射 API
Java 反射指的是在运行状态时,能够获取类的属性和方法或者修改类运行时行为的过程。
java.lang.Class 类提供了很多方法用于获取元数据、检查和改变类运行时的行为。
Java 的反射主要涉及 java.lang 和 java.lang.reflect 包下的类。
反射应用场景举例
java.lang.Class 类
java.lang.Class 主要提供了以下两个功能:
java.lang.Class 类常用方法
Method | Description |
---|---|
1) public String getName() | 返回类名 |
2) public static Class forName(String className)throws ClassNotFoundException | 加载类并返回 Class 对象 |
3) public Object newInstance()throws InstantiationException,IllegalAccessException | 创建实例对象 |
4) public boolean isInterface() | 判断是否是接口 |
5) public boolean isArray() | 判断是否是数组 |
6) public boolean isPrimitive() | 判断是否是原始数据类型 |
7) public Class getSuperclass() | 返回父类 Class 引用 |
8) public Field[] getDeclaredFields()throws SecurityException | 返回类的成员属性字段数组 |
9) public Method[] getDeclaredMethods()throws SecurityException | 返回类的方法数组 |
10) public Constructor[] getDeclaredConstructors()throws SecurityException | 返回类的构造方法数组 |
11) public Method getDeclaredMethod(String name,Class[] parameterTypes)throws NoSuchMethodException,SecurityException | 返回类中指定参数类型的方法 |
怎样获取 Class 对象
有三种方式,如下:
forName() 方法示例
可用于动态加载,当你知道类的全限定名时,可以使用该方式。注意原始数据类型不适用该方法;
- package tmp;
- class Simple
- {
- }
- public class Test
- {
- public static void main(String args[]) throws ClassNotFoundException
- {
- Class<?> c = Class.forName("tmp.Simple");
- System.out.println(c.getName());
- System.out.println(c.getSimpleName());
- }
- }
getClass() 方法示例:
从实例对象中获取 Class 对象
- package tmp;
- class Simple
- {
- }
- public class Test
- {
- void printName(Object obj)
- {
- }
- public static void main(String args[])
- {
- Simple s = new Simple();
- Class<? extends Object> c = s.getClass();
- System.out.println(c.getName());
- System.out.println(c.getSimpleName());
- }
- }
.class 语法示例
作用于类名上,也可应用于原始数据类型,如下所示:
- package tmp;
- public class Test
- {
- public static void main(String args[])
- {
- Class<Boolean> c = boolean.class;
- System.out.println(c.getName());
- Class<Test> c2 = Test.class;
- System.out.println(c2.getName());
- }
- }
判断 Class 对象对应的类型
以下方法可用于判断 Class 对象对应的类型:
1) public boolean isInterface(): 是否对应接口 |
2) public boolean isArray(): 是否对应数组 |
3) public boolean isPrimitive(): 是否对应原始数据类型 |
代码示例:
- package tmp;
- class Simple
- {
- }
- interface My
- {
- }
- public class Test
- {
- public static void main(String args[])
- {
- try
- {
- Class<?> c = Class.forName("tmp.Simple");
- System.out.println(c.isInterface());
- Class<?> c2 = Class.forName("tmp.My");
- System.out.println(c2.isInterface());
- }
- catch (Exception e)
- {
- System.out.println(e);
- }
- }
- }
通过反射创建实例对象
有两种方式,如下:
所以,通常来讲,第二种方式比第一种使用范围更广。
Class 对象调用 newInstance() 方法示例
- package tmp;
- class Simple
- {
- void message()
- {
- System.out.println("Hello Java");
- }
- }
- public class Test
- {
- public static void main(String args[])
- {
- try
- {
- Class<?> c = Class.forName("tmp.Simple");
- Simple s = (Simple) c.newInstance();
- s.message();
- }
- catch (Exception e)
- {
- System.out.println(e);
- }
- }
- }
Hello Java
Constructor 对象调用 newInstance() 方法示例
注意这里可以根据传入参数的类型来得到指定的构造方法,还可以改变构造方法的访问权限限制。
- package tmp;
- import java.lang.reflect.Constructor;
- class Simple
- {
- private String msg;
- void message()
- {
- System.out.println("Hello Java," + msg);
- }
- private Simple(String s){
- this.msg = s;
- }
- }
- public class Test
- {
- public static void main(String args[])
- {
- try
- {
- Class<?> c = Class.forName("tmp.Simple");
- Constructor<?> con = c.getDeclaredConstructor(String.class);
- con.setAccessible(true);
- Simple s = (Simple) con.newInstance("...");
- s.message();
- }
- catch (Exception e)
- {
- System.out.println(e);
- }
- }
- }
Hello Java,...
通过反射调用私有方法
通过反射,我们可以调用其它类的私有方法,主要涉及 java.lang.Class 和 java.lang.reflect.Method 类;
其中主要是用到了 Method 类的 setAccessible 方法和 invoke 方法,前者修改访问权限,后者调用方法。
通过调用有参私有方法示例:
- package tmp;
- import java.lang.reflect.Method;
- class A
- {
- private void cube(int n)
- {
- System.out.println(n * n * n);
- }
- }
- class Test
- {
- public static void main(String args[]) throws Exception
- {
- Class<A> c = A.class;
- Object obj = c.newInstance();
- Method m = c.getDeclaredMethod("cube", new Class[]{ int.class });
- m.setAccessible(true);
- m.invoke(obj, 4);
- }
- }
关于 javap 工具
使用 javap 命令可以反汇编 java 的字节码文件,展示 class 文件中的字段属性、构造方法、普通方法信息;
使用说明:
javap java.lang.Object 示例
javap -c Test 示例:
写个简单的 Test 类,如下:
- package tmp;
- class Simple
- {
- }
- public class Test
- {
- public static void main(String args[])
- {
- System.out.println("Hello");
- }
- }
输入 javap -c Test:
参考资料
基本属于翻译,做了小部分修改
http://www.javatpoint.com/java-reflection
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持 PHPERZ!
来源: http://www.phperz.com/article/17/1219/358414.html