您的位置:首页 > 编程语言 > Java开发

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

2017-05-09 17:18 309 查看
一,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.Class
System.out.print(returnType.getName()+" ");
System.out.print(ms[i].getName()+"(");     //得到方法的名称
Class [] paramTypes=ms[i].getParameterTypes();//得到的是参数列表的类型的类类型 比如int得到int.Class
for (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 stub
String s="hello";

ClassUtil.printClassMessage(s);
}

}
类的名称是:java.lang.String
boolean 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 stub
ArrayList list=new ArrayList<>();
ArrayList<String> list1=new ArrayList<>();
Class c1=list.getClass();
Class c2=list1.getClass();
System.out.println(c1==c2);

}

}返回
true
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: