java反射--高级开发必须懂的

来源:互联网 发布:mysql修改root密码 编辑:程序博客网 时间:2024/05/17 21:06

一,Class类

万事万物皆对象,类也是对象,类是 java.lang.Class 类的对象


这个对象有三种获取方法:

Class c1=ClassName.class;//由类名来获取类类型
ClassName a=new fo();    //由类对象来获取类类型
Class c2=a.getClass();
Class c3=Class.forName("packageName.ClassName");//由Class类的forName方法来获取



二,动态加载类

new 创建对象是静态加载类,在编译时刻就加载可能用到的类

通过动态加载类即用到的类才加载

Class c=Class.forName(arg[0]);  //动态加载类,在运行时刻加载Word w=(Word)c.newInstance();   //通过类类型来创建类对象



三,Class类的基本API操作(获取类方法的类类型)

1.通过对象来获取类类型,然后通过该类类型来获取全部方法及方法的返回值类型,参数,参数类型

public class ClassUtil {public static void printClassMessage(Object obj){Class c=obj.getClass();     //通过对象来获取类类型System.out.println("类的名称是:"+c.getName());Method[] ms=c.getMethods();  //获取该类类型的所有方法的类类型的数组
                for (int i = 0; i < ms.length; i++) {Class returnType=ms[i].getReturnType();  //得到方法返回值类型的类类型,比如String得到String.ClassSystem.out.print(returnType.getName()+" ");System.out.print(ms[i].getName()+"(");     //得到方法的名称Class [] paramTypes=ms[i].getParameterTypes();//得到的是参数列表的类型的类类型 比如int得到int.Classfor (Class class1 : paramTypes) {System.out.print(class1.getName()+" ");}System.out.println(")");}}}

test类

public class ClassTest {public static void main(String[] args) {// TODO Auto-generated method stubString s="hello";ClassUtil.printClassMessage(s);}}
类的名称是:java.lang.Stringboolean equals(java.lang.Object )java.lang.String toString()int hashCode()int compareTo(java.lang.String )int compareTo(java.lang.Object )int indexOf(java.lang.String int )int indexOf(java.lang.String )int indexOf(int int )int indexOf(int )。。。。。。省略,至此获取该String.Class的全部方法


2.

成员变量也是对象,是java.lang.reflect.Field的对象

Field类封装了关于成员变量的操作

getFields()方法获取的是所有的public的成员变量的信息

getDeclaredFields获取的是该类自己声明的成员变量的信息

public static void printClassField(){Field[] fs=c.getDeclaredFields();for(Field field:fs){Class fieldType=field.getType();   //得到成员变量的类型的类类型String typeName=fieldType.getName();  String fieldName=field.getName();  //得到成员变量的名称System.out.println(typeName+" "+fieldName);}}


3.

构造函数也是对象,是java.lang.Construtor中封装了构造函数的信息

getDeclaredConstrutors得到所有的构造函数

public static void printConMessage(Object obj){Class c=obj.getClass();Constructor[] cs=c.getDeclaredConstructors();for (Constructor constructor : cs) {System.out.print(constructor.getName()+"(");Class [] paramTypes=constructor.getParameterTypes();  //得到构造函数的参数列表的类类型for (Class class1 : paramTypes) {System.out.print(class1.getName()+",");}System.out.println(")");}}


三,方法的反射


1,通过方法的名称和方法的参数列表才能唯一决定某个方法

2,方法反射的操作

method.invoke(对象,参数列表)

package reflect;import java.lang.reflect.Method;public class MethodTest {public static void main(String[] args) {A a=new A();Class c=a.getClass();Method m;    try{     m=c.getMethod("print",int.class,int.class);    Object o= m.invoke(a, new Object[]{10,20});  //方法没有返回值就返回null,有返回值返回具体的返回值        System.out.println("=============");        Method m1=c.getMethod("print", new Class[]{"hello".getClass(),"word".getClass()});        Object o1=m1.invoke(a, "hello","word");  //传入对象,方法的实参    }catch(Exception e){    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());}}
结果:
30=============HELLO,word



四,反射的操作都是编译之后的操作

java集合的泛型,实防止错误输入,只在编译阶段有效

public class MethodDemo {public static void main(String[] args) {// TODO Auto-generated method stubArrayList list=new ArrayList<>();ArrayList<String> list1=new ArrayList<>();Class c1=list.getClass();Class c2=list1.getClass();System.out.println(c1==c2);}}
返回

true


0 0
原创粉丝点击