【框架基础】:Java反射机制详解(二)
来源:互联网 发布:hashcode源码 编辑:程序博客网 时间:2024/05/18 03:06
一、Class类
要正确使用Java反射机制就得使用java.lang.Class这个类。它是Java反射机制的起源。当一个类被加载以后,
Java虚拟机就会自动产生一个Class对象。通过这个Class对象我们就能获得加载到虚拟机当中这个Class对象对应的方
法、成员以及构造方法的声明和定义等信息。
反射机制获取类有三种方法,我们来获取Foo类类型:
//第一种方式: Class clazz1 = Class.forName("com.demo.reflect.Foo"); //第二种方式: //Java中每个类型都有class 属性. Class clazz2 = Foo.class; //第三种方式: //Java语言中任何一个Java对象都有getClass()方法 Foo foo = new Foo(); Class clazz3 = foo.getClass(); //clazz3是运行时类(foo的运行时类是Foo)
创建对象:获取类以后我们来创建它的对象,利用newInstance()方法:
Class clazz =Class.forName("com.demo.reflect.Foo"); //创建此Class 对象所表示的类的一个新实例 Object object = clazz.newInstance(); //调用了Foo的无参构造方法
示例代码:
package com.demo.reflect;public class ClassDemo1 {public static void main(String[] args) {//Foo的实例对象如何表示Foo foo1 = new Foo();//foo就表示出来了。//Foo这个类也是一个实例对象,Class类的实例对象,如何表示呢//任何一个类都是Class的实例对象,这个实例对象有三种表示方式//第一种表示方式--->实际在告诉我们任何一个类都有一个隐含的静态成员变量classClass<?> clazz1 = Foo.class;//第二中表达方式 已经知道该类的对象通过getClass()方法Class<?> clazz2 = foo1.getClass();/* * 官网 clazz1 ,clazz2 表示了Foo类的类类型(class type) * 万事万物皆对象, * 类也是对象,是Class类的实例对象 * 这个对象我们称为该类的类类型 *///不管clazz1 or clazz2都代表了Foo类的类类型,一个类只可能是Class类的一个实例对象System.out.println(clazz1 == clazz2);//第三种表达方式Class<?> clazz3 = null;try {clazz3 = Class.forName("com.demo.reflect.Foo");} catch (ClassNotFoundException e) {e.printStackTrace();}System.out.println(clazz2==clazz3);//我们完全可以通过类的类类型创建该类的对象实例---->通过clazz1 or clazz2 or clazz3创建Foo的实例对象try {/* * clazz1.newInstance()这个方法的返回值是Object类型,所以需要进行强制类型转换。 * newInstance()是实现虚拟构造器的一种方法,(虚拟构造器:允许你不知道确切类型, * 但是你必须要正确的创造自己)而clazz1,clazz2,clazz3仅仅只是Class类的引用, * 编译器不具备任何更多信息,只有在创建新实例的时候会得到Object引用(注意是Object引用), * 你要想用这个引用那你必须要向下转型啦,就是这里的强制类型转换。 */Foo foo = (Foo)clazz1.newInstance();//需要有无参数的构造方法foo.print();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}}class Foo{//打印输出方法void print(){System.out.println("foo");}}
运行结果:
对于基本的数据类型和其对应的包装类也有类类型:
package com.demo.reflect;public class ClassDemo2 {public static void main(String[] args) {Class<?> clazz1 = int.class;//int 的类类型Class<?> clazz2 = String.class;//String类的类类型 String类字节码(自己发明的)Class<?> clazz3 = double.class;//double的类类型Class<?> clazz4 = Double.class;//Double类的类类型Class<?> clazz5 = void.class;//void关键字的类类型System.out.println(clazz1.getName());System.out.println(clazz2.getName());System.out.println(clazz2.getSimpleName());//不包含包名的类的名称System.out.println(clazz3.getName());System.out.println(clazz4.getName());System.out.println(clazz4.getSimpleName());//不包含包名的类的名称System.out.println(clazz5.getName());}}
运行结果:
二、反射机制的相关API
通过一个对象获得完整的包名和类名:
package com.demo.reflect;public class TestReflect { public static void main(String[] args) throws Exception { TestReflect testReflect = new TestReflect(); System.out.println(testReflect.getClass().getName());// 结果是com.demo.reflect.TestReflect }}
实例化Class类对象:
package com.demo.reflect;public class TestReflect { public static void main(String[] args) throws Exception { Class<?> clazz1 = null; Class<?> clazz2 = null; Class<?> clazz3 = null; // 一般采用这种形式 clazz1 = Class.forName("com.demo.reflec.TestReflect"); clazz2 = new TestReflect().getClass(); clazz3 = TestReflect.class; System.out.println("类名称 " + clazz1.getName());//结果是com.demo.reflect.TestReflect System.out.println("类名称 " + clazz2.getName());//结果是com.demo.reflect.TestReflect System.out.println("类名称 " + clazz3.getName());//结果是com.demo.reflect.TestReflect }}
获取一个对象的父类与实现的接口:
package com.demo.reflect;import java.io.Serializable;public class TestReflect implements Serializable { public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("com.demo.reflect.TestReflect"); // 取得父类 Class<?> parentClass = clazz.getSuperclass(); System.out.println("clazz的父类为:" + parentClass.getName()); // clazz的父类为: java.lang.Object // 获取所有的接口 Class<?> intes[] = clazz.getInterfaces(); System.out.println("clazz实现的接口有:"); for (int i = 0; i < intes.length; i++) { System.out.println((i + 1) + ":" + intes[i].getName()); } // clazz实现的接口有: // 1:java.io.Serializable }}
获取某个类中的全部构造函数 - 详见下例
通过反射机制实例化一个类的对象:
package com.demo.reflect;import java.lang.reflect.Constructor;public class TestReflect { public static void main(String[] args) throws Exception { Class<?> class1 = null; class1 = Class.forName("net.xsoftlab.baike.User"); // 第一种方法,实例化默认构造方法,调用set赋值 User user = (User) class1.newInstance(); user.setAge(20); user.setName("Rollen"); System.out.println(user); // 结果 User [age=20, name=Rollen] // 第二种方法 取得全部的构造函数 使用构造函数赋值 Constructor<?> cons[] = class1.getConstructors(); // 查看每个构造方法需要的参数 for (int i = 0; i < cons.length; i++) { Class<?> clazzs[] = cons[i].getParameterTypes(); System.out.print("cons[" + i + "] ("); for (int j = 0; j < clazzs.length; j++) { if (j == clazzs.length - 1) System.out.print(clazzs[j].getName()); else System.out.print(clazzs[j].getName() + ","); } System.out.println(")"); } // 结果 // cons[0] (java.lang.String) // cons[1] (int,java.lang.String) // cons[2] () user = (User) cons[0].newInstance("Rollen"); System.out.println(user); // 结果 User [age=0, name=Rollen] user = (User) cons[1].newInstance(20, "Rollen"); System.out.println(user); // 结果 User [age=20, name=Rollen] }}class User { private int age; private String name; public User() { super(); } public User(String name) { super(); this.name = name; } public User(int age, String name) { super(); this.age = age; this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User [age=" + age + ", name=" + name + "]"; }}
获取某个类的全部属性:
package com.demo.reflect;import java.io.Serializable;import java.lang.reflect.Field;import java.lang.reflect.Modifier;public class TestReflect implements Serializable { public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("com.demo.reflect.TestReflect"); System.out.println("===============本类属性==============="); // 取得本类的全部属性 Field[] field = clazz.getDeclaredFields(); for (int i = 0; i < field.length; i++) { // 权限修饰符 int mo = field[i].getModifiers(); String priv = Modifier.toString(mo); // 属性类型 Class<?> type = field[i].getType(); System.out.println(priv + " " + type.getName() + " " + field[i].getName() + ";"); } System.out.println("==========实现的接口或者父类的属性=========="); // 取得实现的接口或者父类的属性 Field[] filed1 = clazz.getFields(); for (int j = 0; j < filed1.length; j++) { // 权限修饰符 int mo = filed1[j].getModifiers(); String priv = Modifier.toString(mo); // 属性类型 Class<?> type = filed1[j].getType(); System.out.println(priv + " " + type.getName() + " " + filed1[j].getName() + ";"); } }}
获取某个类的全部方法:
package com.demo.reflect;import java.io.Serializable;import java.lang.reflect.Method;import java.lang.reflect.Modifier;public class TestReflect implements Serializable { public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("com.demo.reflect.TestReflect"); Method method[] = clazz.getMethods(); for (int i = 0; i < method.length; ++i) { Class<?> returnType = method[i].getReturnType(); Class<?> para[] = method[i].getParameterTypes(); int temp = method[i].getModifiers(); System.out.print(Modifier.toString(temp) + " "); System.out.print(returnType.getName() + " "); System.out.print(method[i].getName() + " "); System.out.print("("); for (int j = 0; j < para.length; ++j) { System.out.print(para[j].getName() + " " + "arg" + j); if (j < para.length - 1) { System.out.print(","); } } Class<?> exce[] = method[i].getExceptionTypes(); if (exce.length > 0) { System.out.print(") throws "); for (int k = 0; k < exce.length; ++k) { System.out.print(exce[k].getName() + " "); if (k < exce.length - 1) { System.out.print(","); } } } else { System.out.print(")"); } System.out.println(); } }}
通过反射机制调用某个类的方法:
package com.demo.reflect;import java.lang.reflect.Method;public class TestReflect { public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("com.demo.reflect.TestReflect"); // 调用TestReflect类中的reflect1方法 Method method = clazz.getMethod("reflect1"); method.invoke(clazz.newInstance()); // Java 反射机制 - 调用某个类的方法1. // 调用TestReflect的reflect2方法 method = clazz.getMethod("reflect2", int.class, String.class); method.invoke(clazz.newInstance(), 20, "张三"); // Java 反射机制 - 调用某个类的方法2. // age -> 20. name -> 张三 } public void reflect1() { System.out.println("Java 反射机制 - 调用某个类的方法1."); } public void reflect2(int age, String name) { System.out.println("Java 反射机制 - 调用某个类的方法2."); System.out.println("age -> " + age + ". name -> " + name); }}
通过反射机制操作某个类的属性:
package com.demo.reflect;import java.lang.reflect.Field;public class TestReflect { private String proprety = null; public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("com.demo.reflect.TestReflect"); Object obj = clazz.newInstance(); // 可以直接对 private 的属性赋值 Field field = clazz.getDeclaredField("proprety"); field.setAccessible(true); field.set(obj, "Java反射机制"); System.out.println(field.get(obj)); }}
反射机制的动态代理:
package com.demo.reflect;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;//定义项目接口interface Subject { public String say(String name, int age);}// 定义真实项目class RealSubject implements Subject { public String say(String name, int age) { return name + " " + age; }}class MyInvocationHandler implements InvocationHandler { private Object obj = null; public Object bind(Object obj) { this.obj = obj; return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object temp = method.invoke(this.obj, args); return temp; }}/** * 在java中有三种类类加载器。 * * 1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。 * * 2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jrelibext目录中的类 * * 3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。 * * 如果想要完成动态代理,首先需要定义一个InvocationHandler接口的子类,已完成代理的具体操作。 */public class TestReflect { public static void main(String[] args) throws Exception { MyInvocationHandler demo = new MyInvocationHandler(); Subject sub = (Subject) demo.bind(new RealSubject()); String info = sub.say("Rollen", 20); System.out.println(info); }}
1 0
- 【框架基础】:Java反射机制详解(二)
- 【框架基础】:Java反射机制详解(二)
- 【框架基础】:Java反射机制详解(一)
- 【框架基础】:Java反射机制详解(三)
- 【框架基础】:Java反射机制详解(一)
- 【框架基础】:Java反射机制详解(三)
- java反射机制基础详解
- java反射机制基础详解
- Java反射机制基础详解
- java反射机制基础详解
- java反射机制基础详解
- Java反射机制基础详解
- Java反射机制基础详解
- 【框架基础】java反射详解
- Java反射机制(框架基础)
- JAVA基础学习(二十七)--反射机制
- 框架基础--反射机制
- java反射机制详解(二)
- 分区表与索引的管理
- Laravel框架5.*自定义常量的方法
- SLAM笔记一——入门介绍
- C内存模型-BSS段、数据段、代码段、堆与栈
- 学历是铜牌,能力是银牌,人脉是金牌,思维是王牌(感触很深)
- 【框架基础】:Java反射机制详解(二)
- svn提交时报错: The working copy needs to be upgraded svn: Working copy 'E:\java\MyEclipse\Workspaces\fram
- 第二期 AOSP 环境搭建、下载和编译 《手机就是开发板》
- Android之数据统计TalkingData集成
- 【Android】导入第三方库时,关于so文件的一些思考
- IPC之Messenger
- NULL, '\0',0 '0'的区别
- fiddler4 测试Web接口
- 前端编程中,如何消除浏览器缓存