Java的反射机制是Java特性之一,反射机制是构建框架技术的基础所在。Java反射机制是指在运行状态中,动态获取信息以及动态调用对象方法的功能。
Java反射有3个动态性质:运行时生成对象实例,运行时调用方法,运行时更改属性。
一、Java反射常用API
使用java反射技术常用的类如下:
Class类:反射的核心类,反射所有的操作都是围绕该类来生成的。通过Class类,可以获取类的属性、方法等内容信息。
Field类:表示类的属性,可以获取设置类中属性的值。
Method类:表示类的方法,可以获取类中方法的信息,或者执行方法。
Constructor类:表示类的构造方法。
二、反射的应用
1、获取类的信息
(1)获取Class对象,常用的有3种方法
①调用对象的getClass()方法
Student s =new Student();//Student为自定义的学生类型
Class c=s.getClass();
②调用类的class属性
Class c=Student.class;//Student为自定义的学生类型
③使用Class类的forName()静态方法。该方法需要传入某个类的全名的字符串,即要在类名前添加完整的包名
Class c=Class.forName("com.pb.jadv.Student");//正确
Class c=Class.forName(Student);//错误
(2)从Class对象获取信息
Class<Student> sc=Student.class;//使用类型.class
①访问Class对应的类所包含的构造方法
获取构造方法
//获取公共的构造方法
Constructor<Student> c = sc.getConstructor(int.class,double.class);
//获取所有的
Constructor<Student> c = sc.getDeclaredConstructor(int.class,double.class,String.class);
②访问Class对应的类所包含的方法
//访问公共的方法
Method method = sc.getMethods(方法名,参数类型);
//访问所有的方法
Method method = sc.getDeclaredMethod(方法名,参数类型);
③访问Class对应的类所包含的属性
Field[] getFields():返回此Class对象所包含的类的public属性
Field[] getDeclaredFields():返回此Class对象所包含的类的全部属性
2、创建对象
通过反射来创建对象有如下两种方式。
①使用Class对象的newInstance()方法创建对象
使用Class对象的newInstance()方法来创建该Class对象对应类的实例,要求该Class对象的对应类有默认构造方法,而执行newInstance()方法时实际上是利用默认构造方法来创建该类的实例。
②使用Constructor对象创建对象
指定构造方法创建Java对象需要如下3个步骤:
获取该类的Class对象
利用Class对象的getConstructor()方法来获取指定构造方法
调用Constructo的newInstance()创建对象
3、访问类的属性
//使用对象强行对属性赋值
Field stuNo = sc.getDeclaredField("stuNo");
stuNo.setAccessible(true);//获取对私有属性取值和赋值的权限
stuNo.set(s,18);
4、访问类的方法
//使用对象调用方法
Method method = sc.getDeclaredMethod("getStuNo");//根据方法名获取方法
method.setAccessible(true);//强行获取权限
Object o = method.invoke(s);//执行对象方法
5、获取父类
Class<? super Student> suc = sc.getSuperclass();//获取父类的Class对象
Constructor<? super Student> cs = suc.getConstructor();//获取父类默认的构造方法
Object object = cs.newInstance();
System.out.println(object);
6、获取接口
Class<?>[] i = sc.getInterfaces();
Class<?> inter = i[0];//获取父接口
具体实例
public interface Talkable {
}
public class Human {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void think(){
System.out.println("胡思乱想");
}
}
public class Student extends Human implements Talkable{
public int stuNo;
private double score;
// private Student() {
// }
public Student(int stuNo, double score) {
this.stuNo = stuNo;
this.score = score;
}
private Student(int stuNo, double score,String name) {
this.stuNo = stuNo;
this.score = score;
setName(name);
}
private int getStuNo() {
return stuNo;
}
private void setStuNo(int stuNo) {
this.stuNo = stuNo;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"stuNo=" + stuNo +
", score=" + score +
'}'+getName();
}
}
public class TestReflect<T> {
public static void main(String[] args) throws Exception {
//1、获取类型Class
Class<Student> sc=Student.class;//使用类型.class
// Student s=new Student();//由于s的类型不能确定具体的对象地址(可能是子类类型)
// Class<?extends Student>sc1=s.getClass();//使用对象.class
// Class<?>sc2=Class.forName("cn.kgc.Student");
//2、获取构造方法并创建对象
// Constructor<Student> c = sc.getConstructor(int.class,double.class);//获取公共的构造方法
Constructor<Student> c = sc.getDeclaredConstructor(int.class,double.class,String.class);//获取所有的
c.setAccessible(true);
Student s=c.newInstance(3,88,"aa");//通过构造方法创建对象
System.out.println(s);
// System.out.println(s.getScore());
System.out.println(s.getName());
//3、使用对象调用方法
// Method method = sc.getDeclaredMethod("getStuNo");//根据方法名获取方法
Method method = sc.getDeclaredMethod("setStuNo", int.class);
method.setAccessible(true);//强行获取权限
// Object o = method.invoke(s);//执行对象方法
method.invoke(s,15);
// System.out.println(o);
System.out.println(s);
//4、使用对象强行对属性赋值
Field stuNo = sc.getDeclaredField("stuNo");
stuNo.setAccessible(true);
stuNo.set(s,18);
System.out.println(s);
//5、获取父类
Class<? super Student> suc = sc.getSuperclass();//获取父类的Class对象
Constructor<? super Student> cs = suc.getConstructor();//获取父类默认的构造方法
Object object = cs.newInstance();
System.out.println(object);
Method think = suc.getMethod("think");
think.invoke(object);
//6、获取接口
Class<?>[] i = sc.getInterfaces();
Class<?> inter = i[0];//获取父接口
}
}