java 反射
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 反射相关的知识,希望对你有一定的参考价值。
1,what?
反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字, 那么就可以通过反射机制来获得类的所有信息。
2,why?
为了支持框架、和网络构建(版主并没有找到合适介绍的的材料,暂且记下这些)。
3,how?
java反射可以做什么?
反射机制主要提供了以下功能:
1,反编译:.class-->.java
2,通过反射机制访问java对象的属性,方法,构造方法等;
这样好像更容易理解一些,下边我们具体看怎么实现这些功能。
准备: 方法
实例.getClass().getName()
getClass() 获取当前类;
getName() 获取类名;
package net.xsoftlab.baike; public class TestReflect { public static void main(String[] args) throws Exception { TestReflect testReflect = new TestReflect(); System.out.println(testReflect.getClass().getName()); // 结果 net.xsoftlab.baike.TestReflect } }
(1),获取类,三种方法:
public class reftest { public static void main(String[] args) { //第一种方式: Class c1 = null; try { c1 = Class.forName("ref.Ref"); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); }
System.out.println(c1.getName()+"01");
//第二种方式: //java中每个类型都有class 属性. Class c2 = Ref.class; System.out.println(c2.getName()+"02"); //第三种方式: //java语言中任何一个java对象都有getClass 方法 Class c3 = new Ref().getClass(); //c3是运行时类 (e的运行时类是Employee) System.out.println(c3.getName()+"03"); } }
tip:在备用方法中我们使用的方法为:
实例.getClass().getName()
在验证获取类的3种方法中,我们使用的方法为 getName(); 这是因为c1,c2,c3本身就是类;
若使用c1.getClass().getName();返回的是Class 类的类类型 // 答案为:java.lang.Class01
另外:方法1知道的关于类的信息较多(路径),
方法3的特别之处在于实例化了对象,通过getClass()获取了当前的类;
方法1,2,3的共同之处在于,你必须知道类名;
(2)实例化对象,方法:newInstance()
Class c2 = Ref.class; //创建此Class 对象所表示的类的一个新实例 try { Object o = c2.newInstance(); //Ref o =(Ref) c2.newInstance(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); }
tip: 采用了方法2获取了类;采用了多肽的方式实例化了Ref, 注意newInstance()方法返回的为Object类型;
(3)获取属性:分为所有的属性和指定的属性:
常用方法:
Field getField(String name)//根据变量名得到相应的public变量
Field[] getFields()//获得类中所以public的方法
Field getDeclaredField(String name)//根据方法名获得public和非public变量
Field[] getDeclaredFields()//获得类中所有的public和非public方法
3.1遍历所有属性:
//获取整个类 Class c = Class.forName("java.lang.Integer"); //获取所有的属性? Field[] fs = c.getDeclaredFields(); //定义可变长的字符串,用来存储属性 StringBuffer sb = new StringBuffer(); //通过追加的方法,将每个属性拼接到此字符串中 //最外边的public定义 sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() +"{\n"); //里边的每一个属性 for(Field field:fs){ sb.append("\t");//空格 sb.append(Modifier.toString(field.getModifiers())+" ");//获得属性的修饰符,例如public,static等等 sb.append(field.getType().getSimpleName() + " ");//属性的类型的名字 sb.append(field.getName()+";\n");//属性的名字+回车 } sb.append("}"); System.out.println(sb);
// 讲解一下Modifier
Modifier 是Java.lang.reflect下的一个类:主要介绍其tosting方法
static String |
toString(int mod) 返回描述指定修饰符中的访问修饰符标志的字符串 |
**此处猜测:java必定是通过修饰符和mod 对应的方式 查找到string值返回。
所以:
Modifier.toString(c.getModifiers()) 返回的为类的修饰符;
c.getSimpleName() 返回类的名称;
Modifier.toString(field.getModifiers()) 返回属性修饰符;
b,返回指定属性:
public static void main(String[] args) throws Exception{ <span style="white-space:pre"> </span>//以前的方式: /* User u = new User(); u.age = 12; //set System.out.println(u.age); //get */ //获取类 Class c = Class.forName("User");
//实例化这个类赋给o
Object o = c.newInstance();
//获取id属性
Field idF = c.getDeclaredField("id");
//打破封装
idF.setAccessible(true);
//使用反射机制可以打破封装性,导致了java对象的属性不安全。 //给o对象的id属性赋值"110"
idF.set(o, "110"); //set //get
System.out.println(idF.get(o));
}
tip: 获取指定的属性,还可以 打破封装赋值;
此处讲解一下Filed,是Java.lang.reflect下的一个类,
最主要的方法是:
get(Object obj) 得到obj里面的value值
set(Object obj, Object value) 设置obj的value值
getModifiers() : 获取属性的修饰
getName() : 获取属性声明时名字
(4)获取方法、构造方法、接口~
方法关键字 |
含义 |
getDeclaredMethods() |
获取所有的方法 |
getReturnType() |
获得方法的放回类型 |
getParameterTypes() |
获得方法的传入参数类型 |
getDeclaredMethod("方法名",参数类型.class,……) |
获得特定的方法 |
|
|
构造方法关键字 |
含义 |
getDeclaredConstructors() |
获取所有的构造方法 |
getDeclaredConstructor(参数类型.class,……) |
获取特定的构造方法 |
|
|
父类和父接口 |
含义 |
getSuperclass() |
获取某类的父类 |
getInterfaces() |
获取某类实现的接口 |
详解:
Method |
getDeclaredMethod(String name, Class... parameterTypes) 返回一个 Method 对象,该对象反映此 Class
对象所表示的类或接口的指定已声明方法。 |
Method[] |
getDeclaredMethods()
返回 Method 对象的一个数组,这些对象反映此 Class
对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。 |
以上是关于java 反射的主要内容,如果未能解决你的问题,请参考以下文章
使用反射在外部JAR / CLASS上调用包含Hibernate事务的方法(Java EE)