反射
Persion p = new Persion();
Class clazz = p.getClass(); // clazz对象中就包含对象p所属的Persion类的所有信息
Class c0 = Persion.class; // 通过类名.class创建指定类的Class实例
Class c1 = p.getClass();
try {
// 通过Class的静态方法forName(String className)来获取一个类的Class实例
// forName(String className)方法中国参数是你要获取Class实例的类的全路径(包名.类名)
Class c2 = Class.forName("day13.Persion"); // 这个是获取Class实例的常用方式
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// move接口
public interface Move {
void move();
}
// study接口
public interface Study {
void studyInfo();
}
// persion父类
public class Persion {
String name;
int age;
}
// student子类
public class Student extends Persion implements Move,Study{
public Student() {
System.out.println("调用的是:Student()");
}
public Student(String school) {
this.school = school;
System.out.println("调用的是:Student(String school)");
}
private Student(String school, int age) {
this.school = school;
this.age = age;
System.out.println("调用的是: Student(String school, int age)");
}
public String school;
private String privateField;
public void showInfo() {
System.out.println("学校是:" + this.school);
}
@Override
public void studyInfo() {
// TODO Auto-generated method stub
System.out.println("学习知识");
}
@Override
public void move() {
// TODO Auto-generated method stub
System.out.println("骑自行车上学");
}
private void test(String name) {
}
public String getSchool() {
return this.school;
}
}
try {
Class clazz = Class.forName("day13.Student");// 获取Student类的Class结构实例
Class superClazz = clazz.getSuperclass();// 获取父类的Class结构实例
System.out.println(superClazz.getName());// day13.Persion
Class[] interfaces = clazz.getInterfaces(); // 获取当前类的所有接口
for(Class c : interfaces) {
System.out.println(c.getName());
// day13.Move
// day13.Study
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Constructor[] cons = clazz.getConstructors();// 获取类的公有的构造方法 返回数字1代表public
for(Constructor c : cons) {
System.out.println("构造方法名称" + c.getName()); // 获取方法名称
System.out.println("构造方法名称" + c.getName() + "的修饰符是:" + c.getModifiers() ); // 获取方法的修饰符
// 构造方法名称day13.Student的修饰符是:1
Class[]paramClazz = c.getParameterTypes();
for(Class pc : paramClazz) {
System.out.println("构造方法名称" + c.getName() + "的参数类型是: " + pc.getName() ); // 获取方法名称
// 构造方法名称day13.Student的参数类型是: java.lang.String
}
}
Constructor[] cons1 = clazz.getDeclaredConstructors(); // 返回类的所有构造方法(包括公有,私有),返回数字2代表private.
for(Constructor c : cons1) {
System.out.println("构造方法名称" + c.getName()); // 获取方法名称
System.out.println("构造方法名称" + c.getName() + "的修饰符是:" + c.getModifiers() );
// 构造方法名称day13.Student的修饰符是:2
Class[]paramClazz = c.getParameterTypes();
for(Class pc : paramClazz) {
System.out.println("构造方法名称" + c.getName() + "的参数类型是: " + pc.getName() ); // 获取方法名称
// 构造方法名称day13.Student的参数类型是: java.lang.String
// 构造方法名称day13.Student的参数类型是: int
}
}
// 如何用反射的构造方法来创建对象
try {
Object obj = clazz.newInstance(); // 相当于调用Student类的无参共有的构造方法
Student stu = (Student)obj; // 调用的是:Student()
Constructor c = clazz.getConstructor(String.class);// 指定获取一个参数并且为String类型的共有的构造方法
Student stu1 = (Student)c.newInstance("第一中学");
// 调用的是:Student(String school)
System.out.println(stu1.school);
// // 第一中学
//通过反射机制,可以强制的调用私有的构造方法。
Constructor c1 = clazz.getDeclaredConstructor(String.class,int.class);// 指定获取两个参数的构造方法
c1.setAccessible(true);// 接触私有的封装
// 如果没有解除封装直接调用会报异常: 私有方法不可调用
// java.lang.IllegalAccessException: Class day13.Test1 can not access a member of class day13.Student with modifiers "private"
Student stu2 = (Student)c1.newInstance("zhangsan",12);
System.out.println(stu2.school + stu.age);
} catch(Exception e) {
e.printStackTrace();
}
// Method[] ms = clazz.getMethods(); // 获取类的所有的公有方法
Method[] ms = clazz.getDeclaredMethods();// 获取类的所有方法包括公有,私有
for(Method m : ms) {
System.out.println("方法名:" + m.getName());
//
System.out.println("返回值类型:" + m.getReturnType());
System.out.println("修饰符:" + m.getModifiers());
Class[] pcs = m.getParameterTypes(); // 获取方法的参数类型,是一个数组,参数有几个,数组内元素个数就有几个
for(Class pc : pcs) {
System.out.println("参数类型:" + pc.getName());
}
}
方法名:test
返回值类型:void
修饰符:2
参数类型:java.lang.String
Field[] fs = clazz.getFields();// 获取类的public属性,包含父类
Field[] fs = clazz.getDeclaredFields();// 获取类的所有属性,本类
for(Field f : fs) {
System.out.println("修饰符:"+ f.getModifiers());
System.out.println("属性的类型" + f.getType());
System.out.println("属性的名称:" + f.getName());
}
///////
Package p = clazz.getPackage();// 获取类所在的包
System.out.println(p.getName()); // day13
// 得到名称是 setInfo ,参数类型是 String,String 的方法
Method m = clazz.getMethod("setInfo", String.class, String.class);
Constructor con = clazz.getConstructor();// 获取无参构造
Object obj = con.newInstance();// 使用无参构造创建对象
m.invoke(obj, "zhangsan","第一中学");// 参数1是需要实例化的对象,后面的参数是当前调用发放的实际参数
// 这个是setInfo(String name,String school方法
// 如果想要调用一个私有方法
Method m1 = clazz.getDeclaredMethod("test", String.class); //
m1.setAccessible(true); // 解除私有封装,下面可以强制调用私有的方法
m1.invoke(obj, "李四");
// 这是私有test(String name)方法
// 有返回值的方法
Method m3 = clazz.getMethod("getSchool");// 获取方法名为getSchool并且没有参数的方法
String school = (String)m3.invoke(obj);// 调用有返回值得但是没有参数的方法
// 反射创建一个对象
Constructor con = clazz.getConstructor();
Student stu = (Student)con.newInstance();
Field f = clazz.getField("school");// 获取名称为school的属性
f.set(stu, "第三中学");
String school = (String)f.get(stu); // 获取stu对象的school属性的值
System.out.println(school);
// 如果是私有属性
Field f1 = clazz.getDeclaredField("privateField");
f1.setAccessible(true);// 私有属性,显示操作后,才可操作;
f1.set(stu, "测试私有属性");
System.out.println(f1.get(stu));
网友评论