java 反射浅析
来源:互联网 发布:java启动exe程序 编辑:程序博客网 时间:2024/06/06 06:59
最近看rpc框架,中间用到了反射,以前也早就听说过反射,用处大大的广。
反射的作用
Java的反射机制、能够在java运行时根据类的路径去获取与路径对应的Class对象。在根据这个类对象去获取类的成员变量、方法、构造这些东西、哪怕他们是私有的。获取到这些东西来做什么?你可以用他们来判断、也可以调用他们去完成某些功能。
反射机制就是专门帮我们做那些重复的有规则的事情。
反射的常用用法:
- 利用打开office软件的demo,不用修改main程序,根据输入动态地调用对应的office,方便扩展。
package office;public class Office { public static void main(String[] args) { Class c = null; try { c = Class.forName(args[0]); } catch (ClassNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } OfficeAble office = null; try { office = (OfficeAble) c.newInstance(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } office.start(); }}
package office;public interface OfficeAble { public void start();}
package office;public class Excel implements OfficeAble{ @Override public void start() { // TODO Auto-generated method stub System.out.println("Excel...start..."); }}
package office;public class Word implements OfficeAble{ @Override public void start() { // TODO Auto-generated method stub System.out.println("Word...start..."); }}
- 下面是反射的常用用法展示:包括获取类类型的几种方法、利用类类型生成对象、获取方法名字、变量、构造函数、函数返回值、函数调用、以及一个表现反射是发生在运行期的。
import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;//打印类中的相关信息,包括方法名、成员变量、构造函数public class ReflectTest3 { //获取类类型的几种方法 public void getClassType() { // one Class c1 = A.class; System.out.println(c1); //second A a = new A(); Class c2 = a.getClass(); System.out.println(c2); System.out.println(c1 == c2); //third Class c3 = null; try { c3 = Class.forName("A"); System.out.println(c3); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } //利用类类型去生成对象 try { A test = (A) c1.newInstance(); test.print(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //打印方法信息 public void printMethodMessage(Object object) { //获取类类型 Class test = object.getClass(); //获取方法名数组,获取返回值、方法名、参数类型 Method[] methods = test.getMethods(); for(int i=0; i<methods.length; ++i) { Class returnType = methods[i].getReturnType(); System.out.print(returnType.getName()+ ""); //返回值 System.out.print(methods[i].getName()+ "("); //方法名 Class[] paramTypes = methods[i].getParameterTypes(); for(Class class1:paramTypes) { System.out.print(class1.getName()); } System.out.println(")"); } } //获取类的public的成员变量 public void printFieldMessage(Object object) { Class c = object.getClass(); Field[] fields = c.getDeclaredFields(); for(Field field: fields) { Class fieldType = field.getType(); String typeName = fieldType.getName(); //获取类型名 String fieldName = field.getName(); //获取变量名 System.out.println(typeName + " " + fieldName); } } //获取构造函数的信息 public void printConMessage(Object object) { Class c = object.getClass(); //构造函数也是对象 Constructor[] constructors = c.getDeclaredConstructors(); for(Constructor cs: constructors) { System.out.print(cs.getName()+"("); //获取构造函数名字 Class[] paramTypes = cs.getParameterTypes(); for(Class paramType:paramTypes) { System.out.print(paramType.getName()+ " "); } System.out.println(")"); } } //方法反射 public void methodReflect() { //获取类类型 A a = new A(); Class c = a.getClass(); //获取方法对象 try { Method m1 = c.getMethod("print"); m1.invoke(a); Method m2 = c.getMethod("print", int.class, int.class); m2.invoke(a, 1, 2); Method m3 = c.getMethod("print", String.class, String.class); m3.invoke(a, "hello", "world"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } //反射是在运行期的,绕过了编译器 //通过arraylist添加不同类型的数据,来看看这个特性 public void runtimeTest() { ArrayList<String> test = new ArrayList<String>(); test.add("hello"); //test.add(20); //编译器报错 Class c = test.getClass(); Method m; try { m = c.getMethod("add", Object.class); m.invoke(test, 20); System.out.println(test.size()); //通过反射,已经将20添加到了ArrayList<String>中,绕过了编译器的语法检查 System.out.println(test); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } //test method public static void main(String[] args) { ReflectTest3 test = new ReflectTest3(); System.out.println("-------------------分割线--获取类类型的几种方法-------------------"); test.getClassType(); System.out.println("-------------------分割线--打印方法信息-------------------"); String s = "hello"; test.printMethodMessage(s); System.out.println("-------------------分割线--打印变量名信息-----------------"); test.printFieldMessage(s); System.out.println("-------------------分割线--打印构造函数信息--------------"); test.printConMessage(s); System.out.println("-------------------分割线--使用方法反射-----------------"); test.methodReflect(); System.out.println("-------------------分割线--反射是在运行期的-----------------"); test.runtimeTest(); }}class A { public void print() { System.out.println("hello,world"); } public void print(int a, int b) { System.out.println(a+b); } public void print(String a, String b) { System.out.println(a.toUpperCase()+","+b.toLowerCase()); }}
运行结果:
-------------------分割线--获取类类型的几种方法-------------------class Aclass Atrueclass Ahello,world-------------------分割线--打印方法信息-------------------booleanequals(java.lang.Object)java.lang.StringtoString()inthashCode()intcompareTo(java.lang.Object)intcompareTo(java.lang.String)intindexOf(java.lang.Stringint)intindexOf(int)intindexOf(intint)intindexOf(java.lang.String)java.lang.StringvalueOf(float)java.lang.StringvalueOf(double)java.lang.StringvalueOf(boolean)java.lang.StringvalueOf([Cintint)java.lang.StringvalueOf([C)java.lang.StringvalueOf(java.lang.Object)java.lang.StringvalueOf(char)java.lang.StringvalueOf(int)java.lang.StringvalueOf(long)charcharAt(int)intcodePointAt(int)intcodePointBefore(int)intcodePointCount(intint)intcompareToIgnoreCase(java.lang.String)java.lang.Stringconcat(java.lang.String)booleancontains(java.lang.CharSequence)booleancontentEquals(java.lang.StringBuffer)booleancontentEquals(java.lang.CharSequence)java.lang.StringcopyValueOf([Cintint)java.lang.StringcopyValueOf([C)booleanendsWith(java.lang.String)booleanequalsIgnoreCase(java.lang.String)java.lang.Stringformat(java.util.Localejava.lang.String[Ljava.lang.Object;)java.lang.Stringformat(java.lang.String[Ljava.lang.Object;)[BgetBytes()[BgetBytes(java.lang.String)voidgetBytes(intint[Bint)[BgetBytes(java.nio.charset.Charset)voidgetChars(intint[Cint)java.lang.Stringintern()booleanisEmpty()intlastIndexOf(int)intlastIndexOf(intint)intlastIndexOf(java.lang.Stringint)intlastIndexOf(java.lang.String)intlength()booleanmatches(java.lang.String)intoffsetByCodePoints(intint)booleanregionMatches(intjava.lang.Stringintint)booleanregionMatches(booleanintjava.lang.Stringintint)java.lang.Stringreplace(charchar)java.lang.Stringreplace(java.lang.CharSequencejava.lang.CharSequence)java.lang.StringreplaceAll(java.lang.Stringjava.lang.String)java.lang.StringreplaceFirst(java.lang.Stringjava.lang.String)[Ljava.lang.String;split(java.lang.String)[Ljava.lang.String;split(java.lang.Stringint)booleanstartsWith(java.lang.String)booleanstartsWith(java.lang.Stringint)java.lang.CharSequencesubSequence(intint)java.lang.Stringsubstring(intint)java.lang.Stringsubstring(int)[CtoCharArray()java.lang.StringtoLowerCase()java.lang.StringtoLowerCase(java.util.Locale)java.lang.StringtoUpperCase(java.util.Locale)java.lang.StringtoUpperCase()java.lang.Stringtrim()voidwait(longint)voidwait(long)voidwait()java.lang.ClassgetClass()voidnotify()voidnotifyAll()-------------------分割线--打印变量名信息-----------------[C valueint hashlong serialVersionUID[Ljava.io.ObjectStreamField; serialPersistentFieldsjava.util.Comparator CASE_INSENSITIVE_ORDERint HASHING_SEEDint hash32-------------------分割线--打印构造函数信息--------------java.lang.String([B )java.lang.String([B int int )java.lang.String([B java.nio.charset.Charset )java.lang.String([B java.lang.String )java.lang.String([B int int java.nio.charset.Charset )java.lang.String(int int [C )java.lang.String([C boolean )java.lang.String(java.lang.StringBuilder )java.lang.String(java.lang.StringBuffer )java.lang.String([I int int )java.lang.String([C int int )java.lang.String([C )java.lang.String(java.lang.String )java.lang.String()java.lang.String([B int int java.lang.String )java.lang.String([B int )java.lang.String([B int int int )-------------------分割线--使用方法反射-----------------hello,world3HELLO,world-------------------分割线--反射是在运行期的-----------------2[hello, 20]
反射的应用
工厂方法、代理+代理=动态代理(应用在spring的AOP上)、ibatis等
下面是我用maven+java反射+注解+jdbc写的一个简单的orm,代码放在github:https://github.com/zy416548283/JDBCSimpleORM
反射优缺点
优点:按名称动态检索信息,让运行中的程序操作这些信息,无需提前硬编码目标类。
缺点:性能问题.
反射原理
待分析
0 0
- 浅析Java反射机制
- java 反射知识浅析
- Java 反射机制浅析
- Java 反射机制浅析
- Java 反射机制浅析
- Java 反射机制浅析
- Java 反射机制浅析
- 浅析java反射机制
- Java反射机制浅析
- java反射机制浅析
- Java 反射机制浅析
- Java反射机制浅析
- java 反射浅析
- Java 反射机制浅析
- java反射机制浅析
- Java反射机制浅析
- Java 反射机制浅析
- Java 反射机制浅析
- Android之自定义checkbox样式
- 暑假集训——贪心专题——D题
- Android手机为什么不同GPU游戏兼容性差别巨大
- win32编程入门-子窗口控件
- Squares-暴力枚举或者二分
- java 反射浅析
- SqlServer 与 MySQL 基本操作语句对比
- p0j 2488 A Knight's Journey
- Android JNI错误--原因和解决办法
- ASM ClassReader failed to parse class file - probably due to a new Java class file version that isn
- Phone状态监听机制
- poj 1837 Balance -DP
- cin、cin.get()、cin.getline()、getline()、gets()函数的用法
- 动态限制EdiText只能输入特定字符