java类的加载
java类的加载是指将.class文件(可能在磁盘,也可能在网络)加载到内存中,并为之生成java.lang.class对象的实例
java中类以其全限定包名作为唯一标识,jvm中则以全限定包名和类加载器作为唯一标识。
jvm中的类加载器有三个层次:根类加载器、扩展类加载器、系统类加载器。分别加载核心类,扩展jar包中的类以及classpath等指定的类
对象具有两种类型:编译时类型和运行时类型。
1:功能
获取类的各个部位对应的对象
Class 类
Constructor 构造器
Method 方法
Field 属性
Annotation 注解
2: 对象准备
2.1 类对象
@Data
public class User {
private Integer id;
@NotBeNull
public String userName;
private String sex;
private Integer grade; //年级
private List<Course> courseList; //课程
private User() {
}
public User(Integer id) {
findById(id);
}
public User(Integer id, String userName, String sex, Integer grade) {
this.id = id;
this.userName = userName;
this.sex = sex;
this.grade = grade;
courseList = new ArrayList<>();
}
private User findById(Integer id) {
return Utils.getUserById(id);
}
public List<User> listAll() {
return Utils.getUsers();
}
}
2.2 接口
/** * 测试匿名类 * 匿名类: 匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,或实现一个接口 * 匿名内部类不能定义构造器。由于匿名内部类没有类名,所以无法定义构造器,但匿名内部类可以初始化块,可以通过初始化块来完成构造器需要完成的工作。 */ public interface AnonymousInterface { String print(String msg); }
2.3 枚举
/** * 枚举 */ public enum StatusEnum {}
2.4 注解
/** * 注解 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) //注解作用到属性上 public @interface NotBeNull {
String value() default "zsc";
}
2.5 工具
public class Utils { public static List<User> getUsers() { User user1 = new User(1, "小夏1", "男", 1); User user2 = new User(2, "小夏2", "男", 2); User user3 = new User(3, "小夏3", "男", 3); User user4 = new User(4, "小夏4", "男", 4); List<User> users = Arrays.asList(user1, user2, user3, user4); return users; } public static User getUserById(final Integer id) { List<User> users = Utils.getUsers(); for (User user : users) { if (user.getId().intValue() == id) { return user; } } return null; } public static List<Course> getCourses(){ Course course1 = new Course(1,"数学","张老师"); Course course2 = new Course(2,"英语","刘老师"); Course course3 = new Course(3,"汉语","王老师"); Course course4 = new Course(4,"法语","宋老师"); List<Course> courses = Arrays.asList(course1, course2, course3, course4); return courses; } public static Course getCourseById( Integer id) { List<Course> courses = Utils.getCourses(); for (Course course : courses) { if (course.getId().intValue() == id) { return course; } } return null; } }
3:反射获取信息
package com.draymond.reflect; import com.draymond.reflect.entity.User; import org.junit.Test; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * 反射获取类的方式 */ public class MainTest { //----------------------------- 获得类相关的方法 ------------------------------- /** * 获取Class * * @throws ClassNotFoundException */ @Test public void test1() throws ClassNotFoundException { Class clazz1 = Class.forName("com.draymond.reflect.entity.User"); System.out.println(clazz1); //结果:class com.draymond.reflect.entity.User User user = new User(1, "小夏1", "男", 1); Class clazz2 = user.getClass(); System.out.println(clazz2); //结果:class com.draymond.reflect.entity.User Class clazz3 = User.class; System.out.println(clazz3); //结果:class com.draymond.reflect.entity.User } /** * 获取类的全路径 */ @Test public void test2() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); String name = clazz.getName(); System.out.println(name); //com.draymond.reflect.entity.User } /** * 获取包的路径 */ @Test public void test3() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); Package clazzPackage = clazz.getPackage(); String packageName = clazzPackage.getName(); System.out.println(packageName); //com.draymond.reflect.entity } /** * 获取类的名称 */ @Test public void test4() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); String simpleName = clazz.getSimpleName(); System.out.println(simpleName); // User } /** * 获得当前类继承的父类的名字 * * @throws Exception */ @Test public void test5() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); Class superclass = clazz.getSuperclass(); System.out.println(superclass); // class java.lang.Object } /** * 获得当前类实现的类或是接口 * * @throws Exception */ @Test public void test6() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); Class[] interfaces = clazz.getInterfaces(); for (Class superclass : interfaces) { System.out.println(superclass); // class java.lang.Object } } //----------------------------- 获得类中属性相关的方法 ------------------------------- /** * 获取所有的public修饰的属性 * * @throws Exception */ @Test public void test7() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); Field[] fields = clazz.getFields(); System.out.println(fields.length); for (Field field : fields) { String fieldName = field.getName(); System.out.println("fieldName==" + fieldName); //userName // boolean aBoolean = field.getBoolean(Integer.class); //field是String类型,不能转为boolean // System.out.println(aBoolean); Class<?> type = field.getType(); String name = type.getName(); // java.lang.String System.out.println(name); } } /** * 获取所有属性(包括私有) * * @throws Exception */ @Test public void test8() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); //暴力可见 String fieldName = field.getName(); //获取属性的名称 Class<?> type = field.getType(); //获取属性的类型 String typeName = type.getName(); } } //------------------------------- 获得类中 Annotation注解 相关的方法 ------------------------ /** * 获取该 类,方法,属性,构造器 上的公有注解对象 * <p> * 获取 User类上标注的 NotBeNull 注解 * * @throws Exception */ @Test public void test9() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); Annotation annotation = clazz.getAnnotation(NotBeNull.class); //获取 User类上标注的 NotBeNull 注解 if (annotation == null) { System.out.println("没有从user中获取到 NotBeNull 注解"); // 备注:没有执行(因为User类上加了该注解) } else { System.out.println("从user中获取到 NotBeNull 注解"); // 从user中获取到 NotBeNull 注解 } } /** * 返回该 类,方法,属性,构造器 所有的公有注解对象 * * @throws Exception */ @Test public void test11() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); Annotation[] annotations = clazz.getAnnotations(); for (Annotation annotation : annotations) { Class<? extends Annotation> annotationType = annotation.annotationType(); String name = annotationType.getName(); String simpleName = annotationType.getSimpleName(); System.out.println("name:" + name); // name:com.draymond.reflect.NotBeNull System.out.println("simpleName:" + simpleName); // simpleName:NotBeNull } } /** * 获取所有注解(包括非public修饰) * 没意义:注解就是public修饰的 * * @throws Exception */ @Test public void test12() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); Annotation[] declaredAnnotations = clazz.getDeclaredAnnotations(); //获取 } //------------------------------ 获得类中构造器相关的方法 ------------------------------ /** * 获取 private 空参构造器 * * @throws Exception */ @Test public void test13() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); Constructor constructor = clazz.getConstructor(); //构造器private String constructorName = constructor.getName(); System.out.println(constructorName); // java.lang.NoSuchMethodException: com.draymond.reflect.entity.User.<init>() } /** * 获取 public 实参构造器 * * @throws Exception */ @Test public void test14() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); Constructor constructor = clazz.getConstructor(Integer.class, String.class, String.class, Integer.class); String constructorName = constructor.getName(); System.out.println(constructorName); // com.draymond.reflect.entity.User } /** * 获取private 构造器 * * @throws Exception */ @Test public void test15() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); Constructor declaredConstructor = clazz.getDeclaredConstructor(); declaredConstructor.setAccessible(true); //暴力破解 String constructorName = declaredConstructor.getName(); System.out.println(constructorName); // com.draymond.reflect.entity.User } /** * 获得该类所有构造方法 * * @throws Exception */ @Test public void test16() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); Constructor[] constructors = clazz.getDeclaredConstructors(); for (Constructor constructor : constructors) { String constructorName = constructor.getName(); System.out.println(constructorName); } } //----------------------- 实例化对象 --------------------------- /** * class不能获取private修饰构造器对应的实例 * * @throws Exception */ @Test public void test17() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); User user = (User) clazz.newInstance(); // java.lang.IllegalAccessException: Class com.draymond.reflect.MainTest can not access a member of class com.draymond.reflect.entity.User with modifiers "private" System.out.println(user); } /** * 通过构造器获取private修饰构造器对应的实例 * * @throws Exception */ @Test public void test18() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); Constructor declaredConstructor = clazz.getDeclaredConstructor(); declaredConstructor.setAccessible(true); User user = (User) declaredConstructor.newInstance(); System.out.println(user); // User(id=null, userName=null, sex=null, grade=null, courseList=null) } /** * 通过构造器获取带参构造器对应的实例 * * @throws Exception */ @Test public void test19() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); Constructor declaredConstructor = clazz.getDeclaredConstructor(Integer.class, String.class, String.class, Integer.class); declaredConstructor.setAccessible(true); User user = (User) declaredConstructor.newInstance(1, "王老师", "数学", 1); System.out.println(user); // User(id=1, userName=王老师, sex=数学, grade=1, courseList=[]) // 备注:getDeclaredConstructor()参数的类型与个数 与 newInstance 类型与个数 一致 } //----------------------- 获得类中方法相关的方法 --------------------- /** * 获取所有的方法(包括private) * * @throws Exception */ @Test public void test20() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { String methodName = method.getName(); System.out.print(methodName + " "); // equals toString hashCode getId getUserName canEqual listAll setSex setGrade getCourseList setUserName setCourseList findById getSex getGrade setId } } /** * 获取单个指定方法 * * @throws Exception */ @Test public void test21() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); // 获取 find 方法,指定参数类型为Integer Method methods = clazz.getDeclaredMethod("findById", Integer.class); methods.setAccessible(true); Constructor constructor = clazz.getDeclaredConstructor(); constructor.setAccessible(true); User user = (User) constructor.newInstance(); // 由于 空参构造器是private,所以不能创建实例 User invoke = (User) methods.invoke(user, 1); System.out.println(invoke); } /** * 强行获取私有构造器对象 * * @throws Exception */ @Test public void test22() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); // 获取 find 方法,指定参数类型为Integer Method methods = clazz.getDeclaredMethod("findById", Integer.class); Constructor declaredConstructor = clazz.getDeclaredConstructor(); User user = (User) declaredConstructor.newInstance(); System.out.println(user); // User(id=null, userName=null, sex=null, grade=null, courseList=null) } //------------------------------- 类中其他重要的方法 -------------------- /** * 是否为注解 * * @throws Exception */ @Test public void test23() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); boolean userIsAnnotation = clazz.isAnnotation(); System.out.println("userIsAnnotation : " + userIsAnnotation); // false Class notBeNullClazz = Class.forName("com.draymond.reflect.NotBeNull"); boolean notBeNullIsAnnotation = notBeNullClazz.isAnnotation(); System.out.println("notBeNullIsAnnotation : " + notBeNullIsAnnotation); // true } /** * 指定注解是否存在指定元素上 * * @throws Exception */ @Test public void test24() throws Exception { Class userClazz = Class.forName("com.draymond.reflect.entity.User"); boolean annotationPresent = userClazz.isAnnotationPresent(NotBeNull.class); System.out.println(annotationPresent); // true } /** * 是否为匿名类 * * @throws Exception */ @Test public void test25() throws Exception { AnonymousInterface anonymousInterface = new AnonymousInterface() { @Override public String print(String msg) { System.out.println(msg); return msg; } }; Class clazz = anonymousInterface.getClass(); boolean anonymousClass = clazz.isAnonymousClass(); System.out.println(anonymousClass); // true } /** * 是否为数组 * * @throws Exception */ @Test public void isArray() throws Exception { char[] chars = new char[10]; Class clazz = chars.getClass(); boolean array = clazz.isArray(); System.out.println(array); } /** * 是否为 枚举 * * @throws Exception */ @Test public void isEnum() throws Exception { Class clazz = StatusEnum.class; boolean anEnum = clazz.isEnum(); System.out.println(anEnum); //true } /** * 是否为**的实例 * * @throws Exception */ @Test public void isInstance() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); User user = new User(1, "zsc", "男", 1); boolean instance = clazz.isInstance(user); System.out.println(instance); //true } /** * 是否为接口 * * @throws Exception */ @Test public void isInterface() throws Exception { Class clazz = AnonymousInterface.class; boolean anInterface = clazz.isInterface(); System.out.println(anInterface); } /** * 是否为局部类 * * @throws Exception */ @Test public void isLocalClass() throws Exception { } /** * 是否为内部类 * * @throws Exception */ @Test public void isMemberClass() throws Exception { } //------------------------- Field类 ---------------------------- /** * 属性与obj相等则返回true(obj是属性名,而不是属性类型) * * @throws Exception */ @Test public void test32() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); Field userName = clazz.getDeclaredField("userName"); userName.setAccessible(true); boolean isString = userName.equals(String.class); // false boolean isUserName = userName.equals(userName); System.out.println(isString); // false System.out.println(isUserName); // true } /** * get属性值 * * @throws Exception */ @Test public void test33() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); Constructor constructor = clazz.getDeclaredConstructor(); constructor.setAccessible(true); User user = (User) constructor.newInstance(); user.setUserName("draymond"); Field userName = clazz.getDeclaredField("userName"); userName.setAccessible(true); Object o1 = userName.get(user); System.out.println(o1); // draymond } /** * set属性值 * * @throws Exception */ @Test public void test34() throws Exception { Class clazz = Class.forName("com.draymond.reflect.entity.User"); Constructor constructor = clazz.getDeclaredConstructor(); constructor.setAccessible(true); Object o = constructor.newInstance(); Field userName = clazz.getDeclaredField("userName"); userName.setAccessible(true); userName.set(o, "zsc"); System.out.println(o); // User(id=null, userName=zsc, sex=null, grade=null, courseList=null) } /** * 获取注解上的值 * * @throws Exception */ @Test public void test35() throws Exception { Class clazz = User.class; Field userNameField = clazz.getDeclaredField("userName"); NotBeNull annotation = userNameField.getAnnotation(NotBeNull.class); String value = annotation.value(); System.out.println(value); //zsc } }
注解开发: https://www.cnblogs.com/draymond/p/12499670.html
5:aop+注解+反射 自动对数据库查询不到的值赋值
(订单详情页面:订单信息+用户信息
单表查订单详情,没有用户信息的;使用代理的方式,自动注入用户信息)
地址:待续