第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > Java —— Reflect反射机制

Java —— Reflect反射机制

时间:2021-11-11 20:29:14

相关推荐

Java —— Reflect反射机制

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

Java反射的作用?

假如有两个程序员,一个程序员在写程序的时需要使用第二个程序员所写的类,但第二个程序员并没完成他所写的类。那么第一个程序员的代码是不能通过编译的。此时,利用Java反射的机制,就可以让第一个程序员在没有得到第二个程序员所写的类的时候,来完成自身代码的编译。

Class类的使用 OOP的世界里,万事万物皆对象。类是谁的对象呢?——类是对象,类是java.lang.Class类的实例对象!There is a class named class.实例:

//有一个类class Foo {void print() {System.out.println("Foo");} }//在main函数里:public static void main(String[] args) {//Foo这个类也是一个实例对象,Class类的实例对象,如何表示呢//任何一个类都是Class类的实例对象,这个实例对象有三种表示方式//1. --实际在告诉我们,任何一个类都有一个隐含的静态成员变量-classClass c1 = Foo.class;//2. 已知该类的对象通过getClass 方法Foo f1 = new Foo();Class c2 = f1.getClass();//c1, c2表示了Foo类的类类型(class type)//指类也是一个对象,是class类的实例对象,这个对象就成为该类的类类型//不管从c1,c2都代表了Foo类的类类型,一个类只可能是Class类的一个实例对象System.out.println(c1 == c2); //true//3.Class c3 = null;try {c3 = Class.forName("com.immoc.reflect.Foo");} catch (ClassNotFoundException e) {// TODO Auto-generated catch block e.printStackTrace();}System.out.println(c3 == c2); //true/** 我们可以通过类的类类型创建对象实例;* 通过c1 or c2 or c3创建Foo类的对象*/try {Foo foo = (Foo)c1.newInstance(); //需要有无参的构造方法 foo.print();} catch (InstantiationException e) {// TODO Auto-generated catch block e.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch block e.printStackTrace();}}

View Code 动态加载类:例如Class.forName("类的全称")不仅表示了类的类类型,还代表了动态加载类 编译时刻加载类是静态加载类、运行时加载类是动态加载new 对象是静态加载类,在编译时刻就需要加载所有可能使用到的类动态加载类: Class c = Class.forName(args[0]);OfficeAble oa = (OfficeAble)c.newInstance(); //通过类类型创建该类的对象实例功能性的类尽量使用动态加载,而非静态加载基本的数据类型,void关键字 都存在类类型Class类的基本API操作

/*** 打印类的信息,包括类的成员函数,成员变量* @param obj*/public static void printClassMessage(Object obj) {//要获取类的信息,首先要获取类的类类型Class c = obj.getClass();//传递的是哪个子类的对象,c就是该类的类类型System.out.println("类的名称是:" + c.getName());/** Method类,方法对象* 一个成员方法就是一个Method对象* getMethod()方法获取的是所有public的函数,包括父类继承而来的*/Method[] ms = c.getMethods();for(Method m : ms) {//得到方法返回值类型的类类型Class returnType = m.getReturnType();System.out.print(returnType.getName() + " ");System.out.print(m.getName() + "(");//获取参数类型——得到的是参数列表的类型的类类型Class[] paramTypes = m.getParameterTypes();for(Class p : paramTypes) {System.out.print(p.getName() + ",");}System.out.println(")");}}

View Code 方法的反射

public static void printMethodMessage(Object obj) {//要获取类的信息,首先要获取类的类类型Class c = obj.getClass();//传递的是哪个子类的对象,c就是该类的类类型System.out.println("类的名称是:" + c.getName());/** Method类,方法对象* 一个成员方法就是一个Method对象* getMethod()方法获取的是所有public的函数,包括父类继承而来的*/Method[] ms = c.getMethods();for(Method m : ms) {//得到方法返回值类型的类类型Class returnType = m.getReturnType();System.out.print(returnType.getName() + " ");System.out.print(m.getName() + "(");//获取参数类型——得到的是参数列表的类型的类类型Class[] paramTypes = m.getParameterTypes();for(Class p : paramTypes) {System.out.print(p.getName() + ",");}System.out.println(")");}}

View Code 如何获取某个方法 方法的名称和方法的参数列表才能唯一决定某个方法方法反射的操作 method.invoke(对象,参数列表)

public class MethodDemo1 {public static void main(String[] args) {/** 要获取print(int, int)方法* 首先获取类的信息(类的类信息)*/A a1 = new A();Class c = a1.getClass();//2. 获取方法,名称和参数列表try {Method m = c.getDeclaredMethod("print", new Class[]{int.class, int.class});//方法的反射操作:用对象调用方法m.invoke(a1, new Object[]{10, 20});} catch (Exception e) {// TODO Auto-generated catch block e.printStackTrace();} }}class A {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());}}

View Code 成员变量的反射 成员变量也是对象,java.lang.reflect.Field, Field类封装了关于成员变量的操作getFields()方法获取的是所有的public的成员变量的信息getDeclaredFields()获取的是该类自己声明的所有成员变量的信息

//首先得到类型,然后得到该变量的名称://如:private int t;public static void printFieldMessage(Object obj) {System.out.println("---------------------------------------------");Class c = obj.getClass();Field[] fs = c.getDeclaredFields();for(Field f : fs) {//得到成员变量的类型的类类型 :intClass fieldType = f.getType();String typeName = fieldType.getName();//得到成员变量的名称 :tString fieldName = f.getName();System.out.println("typeName: " + typeName + " fieldName: " + fieldName);}}

View Code 构造函数的反射

/*** 打印构造函数的信息(构造函数也是对象:java.long.Constructor)* @param obj*/public static void printConMessage(Object obj) {Class c = obj.getClass();Constructor[] cs = c.getDeclaredConstructors();for(Constructor con : cs) {System.out.print(con.getName() + "(");//获取参数列表Class[] paramTypes = con.getParameterTypes();for(Class cl : paramTypes) {System.out.print(cl.getName() + ",");}System.out.println(")");}}

View Code Java类加载机制通过反射了解集合泛型的本质 Java中集合的泛型是防止错误输入的,只在编译阶段有效,编译完之后就无效了。验证:通过方法的反射

public static void main(String[] args) {// TODO Auto-generated method stubArrayList l1 = new ArrayList();ArrayList<String> l2 = new ArrayList<String>();l1.add("hello");l1.add(2); //wrong?是跟JDK版本有关系嘛???Class c1 = l1.getClass();Class c2 = l2.getClass();System.out.println(c1 == c2); //true,说明编译之后集合的泛型是去泛型化得//反射的操作都是编译之后的操作try {Method m = c2.getMethod("add", Object.class);m.invoke(l1, "world");System.out.println(l1.size());} catch (Exception e) {// TODO Auto-generated catch block e.printStackTrace();} }

View Code

应用:通过类的名称来生产一个对象 如:Integer in = (Integer) class.forName(className).newInstance();

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。