反射的概念
Java反射是一种新的操作成员变量、构造方法、普通方法的机制。为了实现对成员变量、构造方法和普通方法的操作,我们需要借助Java自身提供的java.lang包下的Class类和java.lang.reflect包下的反射API 。
Class类
Class类是Java反射机制的入口,封装了一个类或接口的运行时信息,通过调用Class类的方法可以获取这些信息。
Class类的特点:
1.该类在java.lang包中。
2.该类被final修饰,即该类不可以被子类继承。
3.该类实现了Serializable接口。
4.该类的构造方法被private所修饰,即不能通过new关键字创建该类的对象。
获取Class类实例化对象的几种方法
预先设定同包内有一个Student类
以下是Student类的代码,下面的内容将会用到这段代码
package refletc;
public class Student extends Person {
public String name;
private int age;
public Student() {
System.out.println("无参构造方法");
}
private Student(int a,float b) {
System.out.println("sss");
}
public int getAge() {
return age;
}
public void setAge(int age)throws NullPointerException,Exception {
this.age = age;
System.out.println("break");
}
}
class Person{
public long id;
}
1.通过Class类静态方法forName("类包名.类名")获取Class类实例,
例如:Class clazz = Class.forName("refletc.Student");
2.通过class关键字来获取Class类实例
例如:Class clazz = Student.class;
3.还可以通过实例化一个对象来获取Class类实例
例如:Student student = new Student():
Class clazz = student.getclass();
4.获取数组的Class类实例
Class clazz = String [].class;
5.获取数据类型的Class类实例
利用数据类型包装类中的TYPE来获取这个Class类实例
说明:除char(Character) int(Integer)外 byte short等的包装类都为首字母大写
例子:Class clazz = Integer.TYPE;
clazz = Byte.TYPE;
6.获取父类的Class类实例
通过某个子类的Class实例来获取父类的Class类实例
Class clazz = Student.class.getSuperclass();
获取构造方法(通过反射)
获取构造方法数组的途径(两种)
package refletc;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
public class Test {
public static void main(String[] args) throws NullPointerException,Exception{
Class clazz = Student.class;
Constructor [] constructors = clazz.getConstructors();//获取所有public级别的构造方法
constructors = clazz.getDeclaredConstructors();//获取在类中声明的所有构造方法
}
}
获取指定构造方法的途径(两种)
一般形式:clazz.getDeclaredConstructor("数据类型的Class类实例");两种方法的参数相同
package refletc;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
public class Test {
public static void main(String[] args) throws NullPointerException,Exception{
Class clazz = Student.class;
Constructor constructor = clazz.getConstructor();//获取到指定的public级别的构造方法
constructor = clazz.getDeclaredConstructor(Integer.TYPE,Float.TYPE);//获取在类中声明的指定的构造方法
}
}
查看构造方法的信息
package refletc;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
public class Test {
public static void main(String[] args) throws NullPointerException,Exception{
Class clazz = Student.class;
constructor = clazz.getDeclaredConstructor(Integer.TYPE,Float.TYPE);
constructor.getDeclaringClass().getName();//获取到属于哪个类
//获取到构造方法的访问权限
int result = constructor.getModifiers();
String str = Modifier.toString(result);
constructor.getName();//获取到构造方法名包括所属的包
//获取参数列表
Class [] classes = constructor.getParameterTypes();
for (Class class1 : classes) {
System.out.println(class1.getName());
}
//将访问权限的限制解除
constructor.setAccessible(true);
}
}
采用反射来创建对象
package refletc;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
public class Test {
public static void main(String[] args) throws NullPointerException,Exception{
Class clazz = Student.class;
Constructor constructor = clazz.getConstructor();
Object obj = constructor.newInstance(1,2);//也可以是无参的
}
}
反射对于属性值的一系列操作
package refletc;
import java.lang.reflect.Method;
public class Madefildes {
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("refletc.Student");
//1.获取成员变量
Field [] fields = clazz.getFields();//获取到所有public级别的成员变量(包括继承的类中的成员变量)
fields = clazz.getDeclaredFields();//获取到本类中声明的所有级别的成员变量
//获取单个成员变量
Field field = clazz.getField("id");//只能获取到public级别的成员变量
field = clazz.getDeclaredField("name");//可以获取到任意安全级别的成员变量
//2.查看属性信息
Field field = clazz.getDeclaredField("age");
//获取到属性所属的类
clazz = field.getDeclaringClass();
//访问修饰符
int mod = field.getModifiers();
String str = Modifier.toString(mod);
//获取成员变量的数据类型
Class clayy = field.getType();
//获取成员变量名
field.getName();
//3.调用属性
Field field = clazz.getDeclaredField("age");
field.setAccessible(true);
Student student = new Stduent();
field.set(student, 12);//设置指定对象的对应属性值
}
}
反射对于方法的操作
package refletc;
import java.lang.reflect.Method;
public class Madefildes {
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("refletc.Student");
Method [] methods = clazz.getMethods();//获取所有方法包括继承自父类的
methods = clazz.getDeclaredMethods();//获取本类里的方法忽略访问权限
Method method = clazz.getMethod("getAge");//获取到某一个方法,后的参数如没有可不写
method = clazz.getDeclaredMethod("setAge",Integer.TYPE);
clazz = method.getReturnType();//获取到返回值类型
System.out.println(clazz.getName());
Class [] classes = method.getParameterTypes();//获取参数列表
for (Class class1 : classes) {
System.out.println(class1.getName());
}
classes = method.getExceptionTypes();//获取抛出异常类型
for (Class class1 : classes) {
System.out.println(class1.getName());
}
method.setAccessible(true);//忽略访问权限来使用方法
method.invoke(new Student(), 12);//调用其中方法
}
}