学了Java这么长时间,但是就是没有学习反射和注解,因为在我实际的编写代码的过程中还没有用到,但是这学期我想学习Java流行的框架,所以回过头来学习反射和注解的知识。
反射
一开始学习这个概念的时候就感觉没有什么用,经过一篇文章的讲解,对于反射的应用大致有了了解。什么是反射?平时我们都是由类取建造对象,反过来就是反射的概念了,由对象取寻找类对象。类对象,就是用于描述这种类,都有什么属性,什么方法的
获取类对象的三种方法:在JVM中,每一种类就只有一个类对象存在,所以class1和class2和class3相同
package reflection;
public class TextReflect {
public static void main(String[] args) {
try {
Class class1 = Class.forName("reflection.User");
System.out.println(class1);
Class class2 = User.class;
System.out.println(class2);
Class class3 = new User().getClass();
System.out.println(class3);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
当获取类对象时候,会执行类中的静态方法,我觉得就是获取类对象就会执行类加载进JVM这个过程
那我们如何通过类对象来创建对象呢?
第一步:获取类对象
第二步:获取构造器对象
第三步:利用构造器对象获取对象
package reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class TextRel2 {
public static void main(String[] args) {
try {
Class userClass = User.class;
Constructor[] constructors = userClass.getConstructors();
User user = (User) constructors[0].newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
这样的作用是:假如给出一个配置文件,该文件中有一个类名,在测试文件中,只需要读取文件中的类名即可创建出对象,要想创建其他对象,只需修改配置文件即可,不需要修改测试文件中的代码。
除了上面的利用类对象创建对象的用法,类对象还可以修改对象属性和使用对象方法
package reflection;
import java.lang.reflect.Field;
public class TextRel {
public static void main(String[] args) {
User user = new User();
user.setName("yzg");
user.setAge(20);
try {
Field name = user.getClass().getDeclaredField("name");
System.out.println(user.getName());
//因为name是User中的私有属性 声明这个方法才能修改name的值
name.setAccessible(true);
//传入的是一个对象和想要修改之后的值
name.set(user,"新修改的值");
System.out.println(user.getName());
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
getField和getDeclaredField的区别
这两个方法都是用于获取字段
getField 只能获取public的,包括从父类继承来的字段。
getDeclaredField 可以获取本类所有的字段,包括private的,但是不能获取继承来的字段。
(注: 这里只能获取到private的字段,但并不能访问该private字段的值,除非加上setAccessible(true))
package reflection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TextRel3 {
public static void main(String[] args) {
User user = new User();
user.setName("yzg");
try {
System.out.println(user.getName());
Method setName = user.getClass().getMethod("setName", String.class);
setName.invoke(user,"新修改的值");
System.out.println(user.getName());
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
Method setName = user.getClass().getMethod("setName", String.class);
setName.invoke(user,"新修改的值");
这就是反射的大致内容,等学到后面的框架知识我在回来看看这个反射的知识,肯定会有更深的认识!
注解
初学注解,不知道注解到底可以干什么,不过我在网上发现一个比较好的文章,有兴趣的可以看看,我觉得写的挺好得!
我看了几篇文章,里面都提到了反射和注解在框架中能用到,所以等后面学习到框架得时候,再回来复习一遍!