java的反射机制
2018-05-11 本文已影响0人
名字_都被占了
每当我们编写并且编译一个新创建的类java虚拟机就会产生一个对应的Class对象,并且这个Class对象会被保存在同名.class文件里。当我们new一个新对象或者引用静态成员变量时,java虚拟机中的类加载器就会将对应的Class对象加载到java虚拟机中,然后java虚拟机再根据这个Class对象的相关信息创建我们需要的实例对象或提供静态变量的引用值。需要特别注意的是,每个class类,无论创建多少个实例对象,在JVM中都对应同一个Class对象。
几种能够获取Class对象的方法
1:Object.getClass(),通过对象实例获取对应Class对象,注意对于基本类型无法使用该方法获取Class对象。
2:通过类的类型获取Class对象,基本类型也可以使用这种方法,比如Class c=boolean.class;
3:Class.forName(),通过类的全限定名获取Class对象,基本类型无法使用该方法获取Class对象,比如Class c=Class.forName("java.lang.String");
4:Class.getSuperclass(),获得给定类的父类Class
使用总结:
1:只要是获取private修饰的构造方法(Constructor),成员变量(Field),成员方法(Method)的时候,调用的方法中都会包含Declared这个词,public修饰的就不用调用该方法。
2:只要是调用private修饰的构造方法,成员变量,成员方法,都要使用setAccessible方法来跳过权限检查。
示例一:成员变量public,构造方法private的情况下,给new一个实例
public class CeShi {
public static void main(String[] args) {
Class student=Student.class;
try {
Constructor<Student> constructor=student.getDeclaredConstructor(String.class,int.class,String.class);
constructor.setAccessible(true);
try {
Student student1= constructor.newInstance("laoliang",24,"taiyuan");
System.out.println(student1.toString());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
class Student{
public String name;
public int age;
public String address;
private Student(String name,int age,String adderss){
this.name=name;
this.age=age;
this.address=adderss;
}
@Override
public String toString() {
return "名字为"+name+"年龄为"+age+"地址为"+address;
}
}
示例二:成员变量private,构造方法public的情况下,给成员变量赋值
public class CeShi {
public static void main(String[] args) {
Class student=Student.class;
try {
Constructor<Student> constructor=student.getDeclaredConstructor(String.class,int.class,String.class);
try {
Student student1= constructor.newInstance("laofu",22,"xiaoyi");
Field name=student.getDeclaredField("name");
name.setAccessible(true);
name.set(student1,"laoliang");
Field age=student.getDeclaredField("age");
age.setAccessible(true);
age.setInt(student1,24);
Field address=student.getDeclaredField("address");
address.setAccessible(true);
address.set(student1,"taiyuan");
System.out.println(student1.toString());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
class Student{
private String name;
private int age;
private String address;
public Student(String name,int age,String adderss){
this.name=name;
this.age=age;
this.address=adderss;
}
@Override
public String toString() {
return "名字为"+name+"年龄为"+age+"地址为"+address;
}
}
示例三:通过反射来访问private修饰的成员方法
public class CeShi {
public static void main(String[] args) {
Class student=Student.class;
try {
Constructor<Student> constructor=student.getDeclaredConstructor(String.class,int.class,String.class);
try {
Student student1= constructor.newInstance("laoliang",24,"taiyuan");
Method method=student.getDeclaredMethod("getMethod",String.class);
method.setAccessible(true);
String s= (String) method.invoke(student1,"你好啊");
System.out.println(s);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
class Student{
private String name;
private int age;
private String address;
public Student(String name,int age,String adderss){
this.name=name;
this.age=age;
this.address=adderss;
}
@Override
public String toString() {
return "名字为"+name+"年龄为"+age+"地址为"+address;
}
private String getMethod(String canShu){
return "我是私有方法,你输入的参数是"+canShu+",并且你的"+toString();
}