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

java 反射

2015-08-11 16:01 459 查看
类加载方法:

所有类的对象都是Class的实例。

类加载时会先加载static静态部分,并且从父类的static到子类static依次加载。

final语句块会作为宏定义被加载到特殊位置。

Person类:

public class Person {
private String name;
private int age;

public Person() {
// TODO Auto-generated constructor stub
}

public Person(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public void foo(String s) {
System.out.println("superman is batman's!!" + "   s");
}

public void foo(String s, int i) {
System.out.println("superman is batman's!!" + "   s" + i);
}

}


Demo主函数类:

public class ReflectionDemo {

public static void main(String[] args) {
// TODO Auto-generated method stub
Person person = new Person();
Class demo1=null;
Class demo2=null;
Class demo3=null;
try {
// 通过包名加载类
demo1 = Class.forName("reflection.Person");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 使用类实例反推类
demo2 = person.getClass();
// 使用 “类名.class”加载类
demo3 = Person.class;
System.out.println(demo1.getName());
System.out.println(demo2.getName());
System.out.println(demo3.getName());
}

}


输出结果:

reflection.Person
reflection.Person
reflection.Person

使用Class实例化其他类对象:

public static void main(String[] args) throws Exception {
// 异常未处理
Class c = null;
c = Class.forName("reflection.Person");
Person person = (Person) c.newInstance();
person.setName("naruto");
System.out.println("Person.name :" + person.getName());
}


输出:

Person.name :naruto

这其实是调用Person#Person()默认构造方法,当Person()声明为private私有时,Class.forName()方法会报错。因此在一个类中最好有一个无参构造方法。

通过构造器操作类的有参函数及无参函数:

public static void main(String[] args) {
Class c = null;
Person p1;
Constructor[] cons; // 声明一个构造器数组
try {
// 加载Person类
c = Class.forName("reflection.Person");
// 通过Class实例化其他对象
p1 = (Person) c.newInstance();
p1.setName("naruto");
System.out.println("p1.name :" + p1.getName());
// 获取全部构造函数
cons = c.getConstructors();
// 构造Person实例,cons数组中的索引值与Person中构造函数声明时的位置有关,如果位置不对应会报错
Person p2 = (Person) cons[1].newInstance("tom", 21);
System.out.println("p2.name :" + p2.getName() + "p2.age :"
+ p2.getAge());
} catch (Exception e) {
e.printStackTrace();
}

}


输出:

p1.name :naruto
p2.name :tomp2.age :21

获取类实现的所有接口:

public static void main(String[] args) {
try {
Class<?> c1 = Class.forName("reflection.Person");
Class<?>[] inters = c1.getInterfaces();
for (int i = 0; i < inters.length; i++) {
System.out.println(inters[i].getName());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}


输出:

reflection.InterfaceDemo

通过反射获取类信息:

public static void main(String[] args) {
try {
Class<?> class1 = Class.forName("reflection.Person");
// 获取Person类的父类
Class<?> class2 = class1.getSuperclass();
// System.out.println("父类:" + class2.getName());
// 获取全部构造方法
Constructor[] cons = class1.getConstructors();
for (Constructor constructor : cons) {
System.out.println("构造方法名:" + constructor.getName());
// 获取构造方法的访问权限
int no = constructor.getModifiers();
System.out.println("访问权限:" + Modifier.toString(no));
// 每个构造方法的参数
Class p[] = constructor.getParameterTypes();
for (int i = 0; i < p.length; i++) {
System.out.print(p[i].getName() + "   ");
}
System.out.println();
}
// 获取类全部方法信息
Method[] methods = class1.getMethods();
for (int i = 0; i < methods.length; i++) {
// 获取该方法返回值类型
Class<?> retuTypes = methods[i].getReturnType();
// 获取该方法参数类型
Class<?>[] paraTypes = methods[i].getParameterTypes();
// 获取该方法抛出的异常
Class<?>[] exce = methods[i].getExceptionTypes();
System.out.println();
}
// 获取该类全部非私有的属性信息
Field[] fields = class1.getFields();
// 获取该类全部属性信息,包括私有属性
Field[] fields1 = class1.getDeclaredFields();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}


调用其他类的方法:

public static void main(String[] args) {
try {
Class<?> demo = Class.forName("reflection.Person");
Method method = demo.getMethod("foo",String.class,int.class);
method.invoke(demo.newInstance(),"haha",32);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}


如果方法访问修饰符为private需要修改访问权限


public static void main(String[] args) {
try {
Class<?> demo = Class.forName("reflection.Person");
//getDeclaredMethod()可以访问所有方法,不管方法的访问修饰符是什么
Method method=demo.getDeclaredMethod("fun");
//如果方法访问修饰符为private需要修改访问权限
method.setAccessible(true);
method.invoke(demo.newInstance());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}


访问用private修饰的字段也需要修改访问权限:

public static void main(String[] args) {
try {
Class<?> demo = Class.forName("reflection.Person");
Field field=demo.getDeclaredField("name");
field.setAccessible(true);
Person p=(Person) demo.newInstance();
field.set(p, "pepelu");
System.out.println(field.get(p));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: