1.类加载器的作用?
源文件.java ------ Javac编译器 ------字节码文件.class ------- 类加载器-------字节码校验器--------解释器 --------OS
作用:将class文件字节码内容,加载到内存中,静态域转化为方法区的运行时刻的数据结构,然后再堆中生成class对象,
作为方法区数据的访问入口。
2.类缓存?
查找类,一但加载到类加载器中,将维持/缓存一段时间后,JVM会进行垃圾回收。
3.类加载器的分类?
注:util.*基础类库
1.引导类:复杂核心类库的装载C++编写
2.扩展类:负责jre/lib/ext 目录下的jar包 或 ext.dirs下的jar包装载入工作库
3.系统类:把properties中的jar包装入工作库。
4. 双亲委派机制:防止同名包、类与jdk中的相冲突!
加载类时,首先通知appLoader, 是否有缓存 , 能加载即加载;
若无,则通知其父类加载器extLoader , 同上: 是否有缓存 , 能加载即加载;
若无,则通知其父类加载器BootstrapLoader , 同上: 是否有缓存 , 能加载即加载;
若再无?则又一层一层地向子类加载器走,能加载即加载。
若到appLoader,仍然是无缓存,则加载,同时加载到缓存中!
文章图片
这个过程是不停在找自己的父级,所以叫双亲委派机制。
看下概念!双亲委派机制描述:
某个特定的类加载器在接到加载类的请求时,
首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;
只有父类加载器无法完成此加载任务时,才自己去加载。
问题:能不能自己写个类叫java.lang.System?回答:通常情况下不可以,由于类加载采用委托机制。
它会不断查找自己的父类加载器,是否有该同名类,不断递归;而System类是Bootstrap加载器加载的,就算自己重写,
也总是使用Java系统提供的System,自己写的System类根本没有机会得到加载。但是!
可以自己定义一个类加载器来达到这个目的,为了避免双亲委托机制,这个类加载器也必须是特殊的。
由于系统自带的三个类加载器都加载特定目录下的类,
如果我们自己的类加载器放在一个特殊的目录,那么系统的加载器就无法加载,
最终由我们自己的加载器加载。
5.反射创建类对象?
Class对象调用newInstance()方法;
满足:a.类必须有一个无参构造方法;若无,则必须要传入参数,通过invoke方法;
b.类的构造方法需要足够。Declared...
6.通过构造方法创建对象?
通过Class对象调用getDeclaredConstructer(Class ...parameterTypes)取得构造器方法;
向构造器传入对象数组,包含构造器所需的各个参数;
通过Constructer对象实例化对象。
7.调用指定的方法?
getMethod()、invoke()等方法
package com.tencent.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test7 {
//通过反射创建对象
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {Class c1 = Class.forName("com.tencent.reflection.User");
//1.构造对象 - 调用的无参构造器!
User user = (User) c1.newInstance();
System.out.println(user);
//若User未写无参构造,则报错//2.通过构造器创建对象
Constructor constructor = c1.getDeclaredConstructor(String.class , int.class);
User user1 = (User) constructor.newInstance("jx" , 21);
//如果参数为空,会报错.因为User现没有无参构造方法
System.out.println(user1);
//3.利用反射调用普通方法
User user3 = (User)c1.newInstance();
//获得一个方法参数1:方法名参数2:参数类型
Method setName = c1.getDeclaredMethod("setName", String.class);
//invoke激活的意思, (对象 , 方法传参数的值)
setName.invoke(user3 , "jiaxin");
Method setAge = c1.getDeclaredMethod("setAge", int.class);
setAge.invoke(user3 , 21);
System.out.println("user3 = " + user3);
//User{name='jiaxin', age=21}User user4 = (User) c1.newInstance();
Field name = c1.getDeclaredField("name");
name.setAccessible(true);
//必须加! 开启可访问的权限!本身不可操作私有属性,所以需要关闭安全检测.
name.set(user4 , "jx");
System.out.println(user4);
//User{name='jx', age=0}}
}
8.获得类的属性、方法、构造器?
package com.tencent.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
public class Test6 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {Class c1 =Class.forName("com.tencent.reflection.User");
//获得类名字
System.out.println(c1.getName());
//com.tencent.reflection.User
System.out.println(c1.getSimpleName());
//User//获得类属性
Field[] fields = c1.getFields();
for (Field field : fields) {
System.out.println(field);
}fields = c1.getDeclaredFields();
/*
* private java.lang.String com.tencent.reflection.User.name
* private int com.tencent.reflection.User.age
* */
for (Field field : fields) {
System.out.println(field);
}//private java.lang.String com.tencent.reflection.User.name
System.out.println(c1.getDeclaredField("name"));
//私有成员所以用DeclaredMethod[] methods = c1.getDeclaredMethods();
/*
public java.lang.String com.tencent.reflection.User.toString()
public java.lang.String com.tencent.reflection.User.getName()
public void com.tencent.reflection.User.setName(java.lang.String)
public int com.tencent.reflection.User.getAge()
public void com.tencent.reflection.User.setAge(int)
* */
for (Method method : methods) {
System.out.println(method);
}/*
* 总结:带Declared可以查出私有成员/方法
* 如果不带,只能查出public的
* *///获得指定构造器 - 根据参数匹配
Constructor dec = c1.getDeclaredConstructor(String.class , int.class);
System.out.println(dec);
}
}
9.获取泛型信息?
public class Test9 {public static void t1(Map map , List list) {
System.out.println("t1");
}public static Map t2(Map map) {
System.out.println("t2");
return null;
}public static void test1() throws NoSuchMethodException {
Method method = Test9.class.getMethod("t1", Map.class, List.class);
//获取泛型的参数类型
Type[] types = method.getGenericParameterTypes();
for (Type type : types) {
/*
java.util.Map
java.util.List
*/
System.out.println(type);
//判断type是不是一个结构化参数类型ParameterizedType-类型判断
if(type instanceof ParameterizedType) {
Type[] t = ((ParameterizedType) type).getActualTypeArguments();
for (Type type1 : t) {
System.out.println(type1);
}
}
System.out.println("");
}System.out.println("");
}public static void test2() throws NoSuchMethodException {
Method method = Test9.class.getMethod("t2", Map.class);
Type typeReturn= method.getGenericReturnType();
if(typeReturn instanceof ParameterizedType) {
Type[] t = ((ParameterizedType) typeReturn).getActualTypeArguments();
for (Type type : t) {
System.out.println(type);
}
/*
class java.lang.String
class com.tencent.reflection.User
*/
}
}public static void main(String[] args) throws NoSuchMethodException {}
}
10.获取注解信息?
//联系反射操作注解
public class Test10 {public static void main(String[] args) throws NoSuchFieldException {/*
* ORM: Object relationship Mapping 对象关系映射
* */Class c1 = User.class;
//通过反射获得类的注解
Annotation[] annotations =c1.getDeclaredAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}System.out.println("");
//获得注解的value值
TableXin table = (TableXin) c1.getAnnotation(TableXin.class);
String value = https://www.it610.com/article/table.value();
System.out.println(value);
System.out.println("");
//获得注解的属性
Field field = c1.getDeclaredField("name");
System.out.println(field);
FieldXin fieldXin = field.getAnnotation(FieldXin.class);
System.out.println(fieldXin.columnName());
System.out.println(fieldXin.type());
System.out.println(fieldXin.length());
//空指针异常!}
}
11.注:User类
package com.tencent.reflection;
@TableXin("user")
public class User {@FieldXin(columnName = "user_name" , type = "int" , length = 10)
private String name;
@FieldXin(columnName = "user_age" , type = "int" , length = 10)
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public User(){}public String getName() {
return name;
}public void setName(String name) {
this.name = name;
}public int getAge() {
return age;
}public void setAge(int age) {
this.age = age;
}@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
【注解与反射_2 - 小记】
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 技术|为参加2021年蓝桥杯Java软件开发大学B组细心整理常见基础知识、搜索和常用算法解析例题(持续更新...)