Java反射机制能够获取的信息,与应用

一、什么是Java反射机制?

【1】反射机制是在运行状态中,对于任何一个类,都能够知道这个类的所有属性和方法;

【2】对于任意一个对象,都能够调用它的任意一个属性和方法;

像这种动态获取类的信息以及动态调用对象的方法的骚操作称为java语言的反射机制。



二、Java反射机制能够获取及操作哪些信息?

【1】获取类的包名 + 类名

 1 package com.zyy.test.reflect;
 2
 3 public class TestReflect {
 4
 5     public static void main(String[] args) throws ClassNotFoundException {
 6         Class<?> class1 = TestReflect.class;
 7         Class<?> class2 = new TestReflect().getClass();
 8         Class<?> class3 = Class.forName("com.zyy.test.reflect.TestReflect");
 9
10         System.out.println("包名+类名:" + class1.getName());
11         System.out.println("类名" + class1.getSimpleName());
12         System.out.println("包名+类名:" + class2.getName());
13         System.out.println("类名" + class2.getSimpleName());
14         System.out.println("包名+类名:" + class3.getName());
15         System.out.println("类名" + class3.getSimpleName());
16
17         /*
18          打印结果如下:
19             包名+类名:com.zyy.test.reflect.TestReflect
20             类名TestReflect
21             包名+类名:com.zyy.test.reflect.TestReflect
22             类名TestReflect
23             包名+类名:com.zyy.test.reflect.TestReflect
24             类名TestReflect
25         */
26     }
27
28 }



 【2】获取某个类的父类与实现的接口信息

 1 package com.zyy.test.reflect;
 2
 3 import java.io.Serializable;
 4
 5 public class TestReflect implements Serializable{
 6
 7     private static final long serialVersionUID = -8047590384784013451L;
 8
 9     public static void main(String[] args) throws ClassNotFoundException {
10         Class<?> clazz = Class.forName("com.zyy.test.reflect.TestReflect");
11         //获取父类信息
12         System.out.println("父类:" + clazz.getSuperclass().getName());
13         //获取实现的所有接口信息
14         Class<?>[] interfaces = clazz.getInterfaces();
15         for (int i = 0; i < interfaces.length; i++) {
16             System.out.println("接口:" + interfaces[i].getName());
17         }
18
19         /*打印结果如下:
20             父类:java.lang.Object
21             接口:java.io.Serializable
22          */
23     }
24
25 }



【3】获取某个类的构造信息以及使用构造进行赋值

 1 package com.zyy.test.reflect;
 2
 3 import java.lang.reflect.Constructor;
 4 import java.lang.reflect.InvocationTargetException;
 5 import java.math.BigDecimal;
 7
 8 public class TestReflect {
 9
10     public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
11         IllegalArgumentException, InvocationTargetException {
12
13         Class<?> clazz = Class.forName("com.zyy.test.reflect.BookFacaed");
14         Constructor<?>[] constructors = clazz.getConstructors();
15
16         for (int i = 0; i < constructors.length; i++) {
17             System.out.println("构造" + i + constructors[i].getName() + "的参数为:");
18             //获取构造的参数信息
19             Class<?>[] types = constructors[i].getParameterTypes();
20             for (int j = 0; j < types.length; j++) {
21                 System.out.println(types[j].getName() + " ");
22             }
23         }
24
25         /*打印结果:
26              构造0com.zyy.test.reflect.BookFacaed的参数为:
27             java.lang.String
28             java.math.BigDecimal
29             构造1com.zyy.test.reflect.BookFacaed的参数为:
30             java.lang.String
31             构造2com.zyy.test.reflect.BookFacaed的参数为:
32          */
33
34         //实例化拥有2个参数的构造方法
35         BookFacaed bookFacaed = (BookFacaed)constructors[0].newInstance("《数据结构》", new BigDecimal(100));
36         System.out.println(bookFacaed);    //调用实体的toString方法打印
37
38         //通过反射机制直接实例化对象
39         BookFacaed bookFacaed2 = (BookFacaed)clazz.newInstance();
40         bookFacaed2.setName("《数据结构》");
41         bookFacaed2.setPrice(new BigDecimal(100));
42         System.out.println(bookFacaed2);
43     }
44
45 }
46
47 class BookFacaed {
48     private String name;
49
50     private BigDecimal price;
51
52     public BookFacaed () {}
53
54     public BookFacaed (String name) {
55         this.name = name;
56     }
57
58     public BookFacaed (String name, BigDecimal price) {
59         this.name = name;
60         this.price = price;
61     }
62
63     public String getName() {
64         return name;
65     }
66
67     public void setName(String name) {
68         this.name = name;
69     }
70
71     public BigDecimal getPrice() {
72         return price;
73     }
74
75     public void setPrice(BigDecimal price) {
76         this.price = price;
77     }
78
79     @Override
80     public String toString() {
81         return name + "的价格为:" + price;
82     }
83 }



【4】获取某个类的所有属性信息

 1 package com.zyy.test.reflect;
 2
 3 import java.lang.reflect.Field;
 4 import java.lang.reflect.Modifier;public class TestReflect {
 5
 6     public static void main(String[] args) throws ClassNotFoundException {
 7         Class<?> clazz = Class.forName("com.zyy.test.reflect.BookFacaed");
 8         Field[] fields = clazz.getDeclaredFields();
 9         for (int i = 0; i < fields.length; i++) {
10             //获得类属性的修饰符
11             String pri = Modifier.toString(fields[i].getModifiers());
12             //获得类属性的类型
13             Class<?> type = fields[i].getType();
14
15             System.out.println(pri + " " + type.getSimpleName() + " " + fields[i].getName());
16             /*打印结果:
17                 private String name
18                 private BigDecimal price
19              */
20         }
21
22         /*如果要获取类的接口或者父类的属性使用下面的方法获取*/
23         Field[] fields2 = clazz.getFields();
24     }
25
26 }



【5】获取某个类的所有方法及其属性信息

 1 package com.zyy.test.reflect;
 2
 3 import java.lang.reflect.Method;
 4 import java.lang.reflect.Modifier;
 5 import java.math.BigDecimal;
 6
 7
 8 public class TestReflect {
 9
10     public static void main(String[] args) throws ClassNotFoundException {
11         Class<?> clazz = Class.forName("com.zyy.test.reflect.BookFacaed");
12
13         Method[] methods = clazz.getMethods();
14         for (int i = 0; i < methods.length; i++) {
15             System.out.println("方法" + (i + 1));
16             //获取方法的修饰符
17             String pri = Modifier.toString(methods[i].getModifiers());
18             //获取方法的返回类型
19             Class<?> type = methods[i].getReturnType();
20             //获取方法的持有参数
21             Class<?>[] params = methods[i].getParameterTypes();
22             for (int j = 0; j < params.length; j++) {
23                 System.out.println(params[j].getName());
24             }
25             //获取方法的抛出异常
26             Class<?>[] excTypes = methods[i].getExceptionTypes();
27             for (int j = 0; j < excTypes.length; j++) {
28                 System.out.println(excTypes[j].getName());
29             }
30         }
31     }
32
33 }



【6】反射机制调用某个类的某个方法

 1 package com.zyy.test.reflect;
 2
 3 import java.lang.reflect.InvocationTargetException;
 4 import java.lang.reflect.Method;
 5 import java.math.BigDecimal;
 6
 7 public class TestReflect {
 8
 9     public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException,
10         IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
11
12         Class<?> clazz = Class.forName("com.zyy.test.reflect.BookFacaed");
13         //调用BookFacaed的addBook()方法
14         Method method = clazz.getMethod("addBook", String.class);
15         method.invoke(clazz.newInstance(), "《数据结构》");
16     }
17
18 }
19
20 class BookFacaed {
21     private String name;
22
23     private BigDecimal price;
24
25     public BookFacaed () {}
26
27     public BookFacaed (String name) {
28         this.name = name;
29     }
30
31     public BookFacaed (String name, BigDecimal price) {
32         this.name = name;
33         this.price = price;
34     }
35
36     public void addBook(String name) {
37         System.out.println("添加书:" + name);
38     }
39
40     public String getName() {
41         return name;
42     }
43
44     public void setName(String name) {
45         this.name = name;
46     }
47
48     public BigDecimal getPrice() {
49         return price;
50     }
51
52     public void setPrice(BigDecimal price) {
53         this.price = price;
54     }
55
56     @Override
57     public String toString() {
58         return name + "的价格为:" + price;
59     }
60 }



【7】通过反射机制操作某个类的属性

 1 package com.zyy.test.reflect;
 2
 3 import java.lang.reflect.Field;
 4 import java.math.BigDecimal;
 5
 6 public class TestReflect {
 7
 8     public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException,
 9         SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException {
10
11         Class<?> clazz = Class.forName("com.zyy.test.reflect.BookFacaed");
12         Object obj = clazz.newInstance();
13         //调用BookFacaed的name属性,并赋值
14         Field field = clazz.getDeclaredField("name");
15         field.setAccessible(true); //操作属性修饰符为private则必须用此申明
16         field.set(obj, "《数据结构》");
17
18         System.out.println(field.get(obj));
19     }
20
21 }



三、Java反射机制能够帮助我们做什么?

【1】打破泛型的约束

 1 package com.zyy.test.reflect;
 2
 3 import java.lang.reflect.InvocationTargetException;
 4 import java.lang.reflect.Method;
 5 import java.math.BigDecimal;
 6 import java.util.ArrayList;
 7 import java.util.List;
 8
 9 public class TestReflect {
10
11     public static void main(String[] args) throws NoSuchMethodException, SecurityException,
12         IllegalAccessException, IllegalArgumentException, InvocationTargetException {
13
14         List<Integer> list = new ArrayList<Integer>();
15         //设定了以上泛型之后,list集合中是无法插入String或者其他类型的数据的
16         //通过泛型我们便可打破这个约束,代码如下
17         Method method = list.getClass().getMethod("add", Object.class);
18         method.invoke(list, "看插入了一个String数据");
19
20         System.out.println(list.get(0));
21     }
22
23 }



【2】反射机制实现动态代理

  Spring的一个核心设计思想便是AOP(面向切面编程),那么AOP是通过动态代理实现的,而动态代理则用到了反射机制;

  用了反射机制的好处在于,一个代理就能处理所有的委托,而不用一个委托类就创建一个代理;

 1 package com.zyy.test.reflect;
 2
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 import java.lang.reflect.Proxy;
 6
 7
 8 public class TestReflect {
 9
10     public static void main(String[] args) {
11         //创建代理类并绑定委托类
12         FruitProxy proxy = new FruitProxy();
13         Fruit fruit = (Fruit) proxy.bind(new Apple());
14         fruit.eatFruit();
15     }
16
17 }
18
19 interface Fruit {
20     public void eatFruit();
21 }
22
23 //委托类
24 class Apple implements Fruit {
25     public void eatFruit() {
26         System.out.println("eat Apple");
27     }
28 }
29
30 //代理类
31 class FruitProxy implements InvocationHandler{
32     private Object obj;
33
34     //绑定对象
35     public Object bind(Object obj) {
36         this.obj = obj;
37         return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
38     }
39
40     @Override
41     public Object invoke(Object proxy, Method method, Object[] args)
42             throws Throwable {
43         System.out.println("这里添加执行内容,<aop:before/>标签熟悉吧,作用一样");
44         Method result = (Method) method.invoke(obj, args);
45         System.out.println("这里添加执行内容,<aop:after/>标签熟悉吧,作用一样");
46
47         return result;
48     }
49
50 }



【3】反射机制应用于工厂模式

对于普通的工厂,新增一个子类的时候,工厂就需要进行调整,而加入反射机制后,工厂则不需要关心你有多少个子类;

 1 package com.zyy.test.reflect;
 2
 3 public class TestReflect {
 4
 5     public static void main(String[] args) throws InstantiationException,
 6         IllegalAccessException, ClassNotFoundException {
 7
 8         Fruit fruit = (Fruit) Factory.getInstance("com.zyy.test.reflect.Orange");
 9         fruit.eatFruit();
10     }
11
12 }
13
14 interface Fruit {
15     public void eatFruit();
16 }
17
18 class Apple implements Fruit {
19     public void eatFruit() {
20         System.out.println("eat Apple");
21     }
22 }
23
24 class Orange implements Fruit {
25     public void eatFruit() {
26         System.out.println("eat Orange");
27     }
28 }
29
30 class Factory {
31     public static Object getInstance (String className) throws InstantiationException,
32         IllegalAccessException, ClassNotFoundException {
33
34         Object obj = Class.forName(className).newInstance();
35         return obj;
36     }
37
38 }
时间: 2024-10-13 15:59:44

Java反射机制能够获取的信息,与应用的相关文章

Java反射机制的学习

Java反射机制是Java语言被视为准动态语言的关键性质.Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的相关信息,动态地生成此类,并调用其方法或修改其域(甚至是本身声明为private的域或方法). 也许你使用Java已经很长时间了,可是几乎不会用到Java反射机制.你会嗤之以鼻地告诉我,Java反射机制没啥用.或许在J2EE.J2SE等平台,Java反射机制没啥用(具体我也不了解,不多做评论),但是在Android应用开发中,该

Java反射机制--笔记

1.认识Class类 任何一个类都是Class类的实例对象,这个实例对象有三种表示方式. 1 /*java 反射机制*/ 2 // 获取类的方法 3 UserDao userDao = new UserDao(); 4 Class c = UserDao.class; // 1.知道类名 使用.class获取类 5 Class d = userDao.getClass(); // 2.知道对象 使用.getClass()获取类 6 Class m = null; // 3.知道类 使用class

[转载] Java反射机制的学习

本文转载自: http://www.blogjava.net/zh-weir/archive/2011/03/26/347063.html Java反射机制是Java语言被视为准动态语言的关键性质.Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的相关信息,动态地生成此类,并调用其方法或修改其域(甚至是本身声明为private的域或方法). 也许你使用Java已经很长时间了,可是几乎不会用到Java反射机制.你会嗤之以鼻地告诉我,Ja

java 反射机制:运行时的类信息(为框架服务的Bug存在)

反射机制:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 换一种引出反射的说法是:当通过反射与一个未知的类型的对象打交道是,JVM只是简单地检查这个类,看它是属于哪个特定的类(就想RTTI那样).在用它做其他事情之前必须先加载那个类的Class对象.因此,那个类的.class文件对于JVM来说必须是可获取的:那么在本地机器上,要么通过网络获得

【java】java反射机制,动态获取对象的属性和对应的参数值,并属性按照字典序排序,Field.setAccessible()方法的说明【可用于微信支付 签名生成】

方法1:通过get()方法获取属性值 package com.sxd.test.controller; public class FirstCa{ private Integer num; private String name; private Boolean flag; public Integer getNum() { return num; } public void setNum(Integer num) { this.num = num; } public String getNam

Java反射机制demo(四)—获取一个类的父类和实现的接口

Java反射机制demo(四)—获取一个类的父类和实现的接口 1,Java反射机制得到一个类的父类 使用Class类中的getSuperClass()方法能够得到一个类的父类 如果此 Class 表示 Object 类.一个接口.一个基本类型或 void,则返回 null.如果此对象表示一个数组类,则返回表示该 Object 类的 Class 对象. 测试代码: package com.aaron.reflect; public class Demo4 { public static void

java反射机制,通过类名获取对象,通过方法名和参数调

try {//得到对象Class c = Class.forName("完整类名");Object yourObj = c.newInstance();//得到方法Method methlist[] = cls.getDeclaredMethods();for (int i = 0; i < methlist.length; i++) {Method m = methlist[i];}//获取到方法对象,假设方法的参数是一个int,method名为setAgeMethod sAg

Java 反射机制

使用 Java 反射机制可以在运行时期检查 Java 类的信息,检查 Java 类的信息往往是你在使用 Java 反射机制的时候所做的第一件事情,通过获取类的信息你可以获取以下相关的内容: Class 对象 类名 修饰符 包信息 父类 实现的接口 构造器 方法 变量 注解 除了上述这些内容,还有很多的信息你可以通过反射机制获得,如果你想要知道全部的信息你可以查看相应的文档 JavaDoc for java.lang.Class 里面有详尽的描述. 在本节中我们会简短的涉及上述所提及的信息,上述的

Java反射机制浅析

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. "程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言".从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言.但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载.探知.使用