您的位置:首页技术文章
文章详情页

详解JAVA 反射机制

浏览:13日期:2022-08-31 08:23:18

什么是反射?

反射机制是在程序运行状态中,对于任意一个类,都能够获取这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制。

反射的作用

1.可以实现简单的反编译,获取类中的属性和方法等基本信息,.class—>java

2.通过反射机制获取类的属性、方法等

在使用eclipse时,通过对象引用.的方式,eclipse就会将这个对象中的所有属性和方法展示出来,这个就是利用的反射机制。其实反射应用最多的地方就是将来要学习的框架,例如spring、spring MVC、Mybatis、hibernate、Struts等等

反射的优点

提高程序的灵活性和扩展性。使用反射机制后,程序在创建对象的时候不用使用new关键字写死在程序中了,而是从配置文件中进行读取,这样可以提高程序的灵活性

反射的缺点

影响性能。使用反射时,代码量稍微多点,并且是要动态的将读取类,所以会影响性能。下面例子可能不太恰当,不过希望能够帮助你更好地了解,比如你要做汽车:

正常的方式是司机停车,你开门上车。动态的方式就是司机不停车,只降低车速,然后你跑着开门上车。

破坏封装性。

Class对象

在类加载器将.class文件读取到内存中的时候,jvm会创建这个.class文件的对象,并且只创建一个存放到jvm的方法区内存中,在java.lang包下有个Class类,这个类就是.class文件的对象类型,任何类在被使用时,都会创建这个类的Class对象。除此之外,在java.lang.reflect包下面的类也跟反射有关。创建一个Person类:

package com.sutaoyu.reflect;public class Person { private String name; public Person() { System.out.println('Person类的构造方法'); } public Person(String name) { this.name = name; } public void sing() { System.out.println('唱歌'); } public void setName(String name) { this.name = name; } public String getName() { return name; }}

获取这个Person类的Class对象有三种方式:

//第一种方式://c1引用的对象代表整个Person类Class c1 = Class.forName('com.monkey1024.reflect.Person');//第二种方式://java中每个类型都有 class 属性.Class c2 = Person.class;//第三种方式://java语言中任何一个java对象都有getClass 方法Person p = new Person();Class c3 = e.getClass(); //因为Person这个类在JVM中只有一个,所以c1,c2,c3的内存地址是相同的,指向堆中唯一的Class对象.System.out.println(c1==c2); //trueSystem.out.println(c2==c3); //true

使用反射将.class文件读取到内存中

将上面的Person.java文件删除,留下Person.class文件。

使用反射将Person.class文件读取到内存中

package com.sutaoyu.reflect;public class RefectTest02 { public static void main(String[] args) { try { //读取时需要加上类的包名 Class clazz = Class.forName('com.sutaoyu.reflect.Person'); Object o = clazz.newInstance(); System.out.println(o); }catch(ClassNotFoundException e) { e.printStackTrace(); }catch(InstantiationException e) { e.printStackTrace(); }catch(IllegalAccessException e) { e.printStackTrace(); } }}

使用反射获取类中的属性

下面程序在获取类中的属性之后,将.class文件中的属性反编译并打印出来了。

package com.sutaoyu.reflect;import java.lang.reflect.Field;import java.lang.reflect.Modifier;public class ReflectTest04 { public static void main(String[] args) throws ClassNotFoundException { Class c = Class.forName('java.lang.Integer'); //获取类中所有的属性 Field[] field = c.getDeclaredFields(); //使用反射反编译 StringBuilder sb = new StringBuilder(200); sb.append(Modifier.toString(c.getModifiers()) + ' class '+c.getSimpleName() + '{n'); //访问权限修饰符 String s = Modifier.toString(f.getModifiers()); if(!''.equals(s)) { sb.append(Modifier.toString(f.getModifiers()) + ''); }//属性的类型名称 Class type = f.getType(); sb.append(f.getName() + ';n');//属性的名字 sb.append('}');System.out.println(sb.toString()); }}

使用反射获取类中指定的属性并赋值

package com.sutaoyu.reflect;import java.lang.reflect.Field;/** * 使用反射获取类中指定的属性,并且为其赋值 * */public class ReflectTest05 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException { Class c = Class.forName('com.monkey1024.reflect.User'); /*//获取指定属性的Field对象 Field f = c.getDeclaredField('name'); //创建对象 Object o = c.newInstance(); //给o对象上的name属性赋值为张三 f.set(o, '张三'); //获取o对象上的name属性的值 System.out.println(f.get(o));*/ Field f = c.getDeclaredField('age'); Object o = c.newInstance(); //从外部打破封装性 f.setAccessible(true); f.set(o, 20); System.out.println(f.get(o)); }}

使用反射获取类中的方法

下面程序将.class文件中的方法反编译并打印出来了

User类:

package com.sutaoyu.reflect;import java.util.Date;public class User { private int age; public String name; protected Date birthday; boolean sex; public void m1(){ } public static void m2(){ } private String m3(){ return ''; } public void m4(int i, String s){ } public String m5(String s, int i){ return s + ' , ' + i; }}

测试类:

package com.sutaoyu.reflect;import java.lang.reflect.Method;import java.lang.reflect.Modifier;/** * 使用反射获取类中的方法 * */public class ReflectTest06 { public static void main(String[] args) throws ClassNotFoundException { //Class c = Class.forName('com.monkey1024.reflect.User'); Class c = Class.forName('java.lang.Object'); //获取类中所有方法 Method[] method = c.getDeclaredMethods(); /*for(Method m : method){ //方法修饰符 System.out.println(Modifier.toString(m.getModifiers())); //方法的返回值类型 Class type = m.getReturnType(); System.out.println(type.getSimpleName()); //方法名 System.out.println(m.getName()); //方法参数 Class[] param = m.getParameterTypes(); for(Class p : param){System.out.println(p.getSimpleName()); } }*/ //反编译将User类中的方法打印 StringBuilder sb = new StringBuilder(200); sb.append(Modifier.toString(c.getModifiers()) + ' class ' + c.getSimpleName() + '{n'); for(Method m : method){ sb.append('t'); //方法的修饰符 sb.append(Modifier.toString(m.getModifiers()) + ' '); //方法的返回值类型 Class type = m.getReturnType(); sb.append(type.getSimpleName() + ' '); //方法名 sb.append(m.getName() + ' '); //方法参数 sb.append('('); Class[] param = m.getParameterTypes(); for(int i=0; i<param.length; i++){if(i == param.length-1){ sb.append(param[i].getSimpleName());}else{ sb.append(param[i].getSimpleName()); sb.append(' ,');} } sb.append(')'); sb.append('{}n'); } sb.append('}'); System.out.println(sb.toString()); }}

使用反射调用类中的方法

package com.sutaoyu.reflect;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;/** * 使用反射调用类中的方法 * */public class ReflectTest07 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Class c = Class.forName('com.monkey1024.reflect.User'); //获取方法 Method method = c.getDeclaredMethod('m5', String.class, int.class); //创建对象 Object o = c.newInstance(); Object result = method.invoke(o, 'admin', 10); System.out.println(result); }}

使用反射获取构造方法

package com.sutaoyu.reflect;import java.lang.reflect.Constructor;import java.lang.reflect.Modifier;/** * 使用反射获取类中的构造方法 * */public class ReflectTest08 { public static void main(String[] args) throws ClassNotFoundException { Class c = Class.forName('java.lang.StringBuffer'); //获取类中所有的构造方法 Constructor[] con = c.getDeclaredConstructors(); for(Constructor co : con){ //获取修饰符 System.out.println(Modifier.toString(co.getModifiers())); //获取方法名 System.out.println(co.getName()); //获取方法参数 Class[] type = co.getParameterTypes(); for(Class t : type){System.out.println(t.getSimpleName()); } } }}

使用反射获取父类和父接口

package com.monkey1024.reflect;/** * 使用反射获取父类和父接口 * */public class ReflectTest09 { public static void main(String[] args) throws ClassNotFoundException { Class c = Class.forName('java.lang.StringBuffer'); //获取父类 Class sup = c.getSuperclass(); System.out.println(sup.getName()); //获取父接口 Class[] inter = c.getInterfaces(); for(Class i : inter){ System.out.println(i.getName()); } }}

以上就是详解JAVA 反射机制的详细内容,更多关于JAVA 反射机制的资料请关注好吧啦网其它相关文章!

标签: Java
相关文章: