平常我们都是通过一个类,通过new这个类来调用这个类的方法属性
举个User类的例子
当我们new这个User时,会在方法区里加载一个User.class文件,随后在栈里创建一个Class类对象,加载User属性,在堆里开辟一个user的空间
那我们要是已知道这个类的全路径,怎么来加载这个类呢?————反射技术
一.什么是反射技术?
反射(Reflection)是Java的特征之一,它允许运行中的Java程序获取自身的信息,并且可以操作类或对象的内部属性。具体来说,通过反射可以在运行时获得程序或程序集中每一个类型的成员和成员的信息。与一般的对象类型在编译期就确定下来不同,Java反射机制可以动态地创建对象并调用其属性,这样的对象的类型在编译期是未知的。因此,通过反射机制可以直接创建对象,即使这个对象的类型在编译期是未知的。
二.反射的使用
当我们拿到一个类的全路径时,我们就可以通过反射技术来加载这个类
通过Class文件得到Class类对象,就可以获得到这个类的相应信息,下面来举个例子
定义一个User类
public class User{
//定义一个私有的属性和两个共有的属性
private int age;
public String name;
public String pwd;
//定义一个方法,以及写get和set方法和toString方法
public void speak(){
System.out.println(name + "说:你好呀~");
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
@Override
public String toString() {
return "User{" +
"age=" + age +
", name='" + name + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
(1)得到类的实例
newInstance() --- 会调用类的构造方法-->空参构造方法
(2)得到类的属性
举例一些个别的属性
getFiled()
getFileds() ---获取类内部已经定义好的公有的属性以及继承父类的定义好的公有的属性
getDeclaredFields() --- 获取类里面已经定义好的所有属性
getDeclaredField() --- 获取类里面定义好的某个属性
setAccessible --- 设置属性的可访问权限,true就是可访问,false就是不可访问
public class Test {
public static void main(String[] args) {
try {
Class<?> aClass = Class.forName("com.cykj.pojo.User");
//通过反射的技术得到一个类的实例
User o = (User) aClass.newInstance();
System.out.println(o);
//通过反射技术得到User类里面的属性
Field[] declaredFields = aClass.getDeclaredFields();
System.out.println(Arrays.toString(declaredFields));
//--[private int com.cykj.pojo.User.age, public java.lang.String com.cykj.pojo.User.name, public java.lang.String com.cykj.pojo.User.pwd]
System.out.println(declaredFields[0]);
//--private int com.cykj.pojo.User.age
//获取单个属性
Field name = aClass.getDeclaredField("name");
System.out.println(name);
//--public java.lang.String com.cykj.pojo.User.name
//获取单个属性并设置值
name.set(o,"zhangsan");
System.out.println(o);
Field age = aClass.getDeclaredField("age");
//User里面的age是私有的,我们在外部是访问不到的,用setAccessible(true)就可以将访问权限设置可见
age.setAccessible(true);
age.set(o,18);
System.out.println(o);
}
}
}
(3)得到里面的方法
getDeclaredMethods()
getDeclaredMethod()
getMethods()
getMethod()
(4)类里面的注解
三.在什么时候会用到反射技术
编写一些程序时,对程序中的一些类名或方法名不能在程序中写死,而是根据配置文件中的某个参数决定。在这种情况下,反射可以用于在运行时根据参数来动态决定使用的类或方法。
在程序运行过程中,对于某个对象并不知其确切的类名,但知道其方法名和参数,或者知道其内部的实例变量。这时可以使用反射来调用该方法或访问该实例变量。
在调用一些第三方库或使用其他框架层或系统层API时,这些库或API的版本可能会变化很大。比如某些类中的某些方法在低版本中没有而高版本中添加,或者某些类在低版本和高版本有很大不同。这个问题也可以使用反射机制部分解决。