反射
含义:将类的字段和方法用对象来表示。
作用:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的法的功能称为java语言的反射机制。
为测试创建User对象和Student对象
public class User {
private String name;
public String loginName;
private User(String loginName){
this.loginName = loginName;
}
public User(){
}
}
public class Student extends User{
private String num;
public int classId;
public Student(){
}
private Student(String num){
this.num = num;
}
}
获取类的字节码对象
每个类被加载之后,系统就会为该类生成一个对应的字节码对象,通过该字节码对象就可以访问到JVM中的对应的类。在Java中获得Class对象通常有三种方式
以Student类为例
//方式一 Class<Student> clazz1 = Student.class; //方式二 Class<Student> clazz2 = (Class<Student>)Class.forName("com.test.Student");//参数为类的全限定名 //方式三 Class<Student> clazz3 = (Class<Student>) new Student().getClass();
反射字段
方法
案例
public class Test {
public static void main(String[] args) throws Exception {
//获取类对象
Class<Student> clazz1 = Student.class;
System.out.println("------------getFields()-----------");
Field[] fields = clazz1.getFields();
for(Field field : fields){
System.out.println(field.getName());
}
System.out.println("------------getField(String name)-----------");
System.out.println(clazz1.getField("loginName"));
System.out.println("------------getDeclaredFields()-----------");
fields = clazz1.getDeclaredFields();
for(Field field : fields){
System.out.println(field.getName());
}
System.out.println("------------getDeclaredField(String name)-----------");
Field field = clazz1.getDeclaredField("num");
System.out.println(field);
System.out.println("-----------------------设置、获取--------------------------");
Student student = new Student();
Field classIdField = clazz1.getField("classId");
//常用操作
//设置
//获取
//给student对象的classId设置值为1
classIdField.set(student, 1);
System.out.println(classIdField.get(student));
System.out.println(student.classId);
Field numField = clazz1.getDeclaredField("num");
//设置强行访问
numField.setAccessible(true);
numField.set(student, "10");
System.out.println(numField.get(student));
}
}
反射方法
方法
案例
public class Test2 { public static void main(String[] args) throws Exception { Class<Student> clazz = Student.class; System.out.println("-------------getMethods()-------------"); Method methods [] = clazz.getMethods(); for(Method method : methods){ System.out.println(method.getName()); } System.out.println("-------------getMethod(String name, Class<?>... parameterTypes)-------------"); Method method = clazz.getMethod("say"); System.out.println(method); method = clazz.getMethod("say",String.class); System.out.println(method); method = clazz.getMethod("say",String.class,int.class); System.out.println(method); System.out.println("-------------getDeclaredMethods()-------------"); methods = clazz.getDeclaredMethods(); for(Method methodTemp : methods){ System.out.println(methodTemp.getName()); } System.out.println("-------------getDeclaredMethod(String name, Class<?>... parameterTypes)-------------"); method = clazz.getDeclaredMethod("cal",int.class,int.class); System.out.println(method); System.out.println("------------------调用----------------------"); Student student = new Student(); method.setAccessible(true); int result = (int) method.invoke(student,1,2); System.out.println(result); //destroy方法 Method staticMethod = clazz.getDeclaredMethod("destroy"); staticMethod.setAccessible(true); staticMethod.invoke(null); } }
放射构造方法
方法
案例
public class Test3 {
public static void main(String[] args) throws Exception {
Class<Student> clazz = Student.class;
//获取public的构造器
System.out.println("-------------getConstructors()-----------");
Constructor<Student> [] constructors = (Constructor<Student>[]) clazz.getConstructors();
for( Constructor<Student> constructor : constructors ){
System.out.println(constructor.getName());
}
//获取指定public的构造器
//clazz.getConstructor(parameterTypes)
//获取所有的构造器
System.out.println("-------------getDeclaredConstructors()-----------");
constructors = (Constructor<Student>[]) clazz.getDeclaredConstructors();
for( Constructor<Student> constructor : constructors ){
System.out.println(constructor.getName());
}
//获取指定的构造器
System.out.println("-------------getDeclaredConstructor(Class<?>... parameterTypes)-----------");
Constructor<Student> privateConstructor = clazz.getDeclaredConstructor(String.class);
System.out.println(privateConstructor);
//使用构造器创建对象
System.out.println("--------------------创建对象-------------------");
privateConstructor.setAccessible(true);
Student student = privateConstructor.newInstance("110");
System.out.println(student);
System.out.println("无参构造器");
Student.class.newInstance();
}
}
放射main方法
案例
public class TestMain {
public static void main(String[] args) {
System.out.println("反射main");
}
}
public class Test{
public static void main(String[] args) throws Exception, SecurityException {
Class<TestMain> clazz = TestMain.class;
Method mainMethod = clazz.getMethod("main", String[].class);
System.out.println(mainMethod);
//调用
mainMethod.invoke(null,new Object[]{new String[]{"a","b"}});
//如下都是错误的
//mainMethod.invoke(null, "a","b"); //可变参数??
//mainMethod.invoke(null,new String[]{"a","b"} ); //可变参数??
}
}