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")); //私有成员 所以用Declared
Method[] 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<String , User> map , List<User> list) {
System.out.println("t1");
}
public static Map<String , User> t2(Map<String , User> 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.lang.String, com.tencent.reflection.User>
java.util.List<com.tencent.reflection.User>
*/
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 = 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 +
'}';
}
}