
类加载的作用:将 class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后在堆中生成一个代表这个类的java.lang.Class对象,作为方法区中类数据的访问入口。

类缓存:标准的JavaSE类加载器可以按要求查找类,但一旦某个类被加载到类加载器中,它将维持加载(缓存)一段时间。不过JVM垃圾回收机制可以回收这些 Class对象。
类加载器作用是用来把类(class)装载进内存的。

Java
package com.lingstudy.reflection;public class Test07 {public static void main(String[] args) throws ClassNotFoundException {//获取系统类的加载器ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();System.out.println(systemClassLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2//获取系统类加载器的父类加载器-->扩展类加载器ClassLoader parent = systemClassLoader.getParent();System.out.println(parent);//sun.misc.Launcher$ExtClassLoader@1540e19d//获取扩张类加载器的父类加载器-->根加载器(c/c++)ClassLoader parent1 = parent.getParent();System.out.println(parent1);//null 无法直接获取//测试当前类是哪个加载器加载的ClassLoader classLoader = Class.forName("com.mjane.reflection.Test07").getClassLoader();System.out.println(classLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2//测试JDK内置的类是哪个加载器加载的classLoader = Class.forName("java.lang.Object").getClassLoader();System.out.println(classLoader);//null 根加载器加载的//如何获得系统类加载器可以加载的路径System.out.println(System.getProperty("java.class.path"));/*E:\JAVA\jdk-8u131-windows-x64_8.0.1310.11\jre\lib\charsets.jar;E:\JAVA\jdk-8u131-windows-x64_8.0.1310.11\jre\lib\deploy.jar;E:\JAVA\jdk-8u131-windows-x64_8.0.1310.11\jre\lib\ext\access-bridge-64.jar;D:\IDEA\projects\AnnotationStudy\out\production\AnnotationStudy;D:\IDEA\IntelliJ IDEA 2019.2.3\lib\idea_rt.jar...................*/}}

Field、Method、Constructor、Superclass、Interface、Annotation
实现全部接口
所继承的父类
全部的构造器
全部的方法
全部的Field
注解

Java
package com.lingstudy.reflection;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;//获得类的信息public class Test08 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {Class c1 = Class.forName("com.mjane.reflection.User");//获得类的名字System.out.println(c1.getName());//获得User类的包名 + 类名System.out.println(c1.getSimpleName());//获得User类的类名//获得类的属性Field[] fields = c1.getFields();//只能找到public属性// for (Field field : fields) {// System.out.println(field);// }fields = c1.getDeclaredFields();//可以找到全部的属性for (Field field : fields) {System.out.println(field);}//获得指定属性的值Field name = c1.getDeclaredField("name");System.out.println(name);//获得类的方法System.out.println("==================");Method[] methods = c1.getMethods();//获得父类及本类的所有public方法for (Method method : methods) {System.out.println("正常的:" + method);}methods = c1.getDeclaredMethods();//获得本类的所有方法for (Method method : methods) {System.out.println(method);}System.out.println("==================");//获得指定的方法//重载Method getName = c1.getMethod("getName", null);Method setName = c1.getMethod("setName", String.class);System.out.println(getName);System.out.println(setName);System.out.println("==================");//获得指定构造器Constructor[] constructors = c1.getConstructors();//获得publicfor (Constructor constructor : constructors) {System.out.println(constructor);}constructors = c1.getDeclaredConstructors();//获得全部的for (Constructor constructor : constructors) {System.out.println(constructor);}//获得指定的构造器Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);System.out.println("指定的构造器:"+declaredConstructor);}}

在实际的操作中,取得类的信息的操作代码,并不会经常开发。
一定要熟悉java.lang.reflect包的作用,反射机制。
如何取得属性、方法、构造器的名称,修饰符等。

创建类的对象:调用 Class对象的newlnstance()方法
1)类必须有一个无参数的构造器。
2)类的构造器的访问权限需要足够。

思考?难道没有无参的构造器就不能创建对象了吗?只要在操作的时候明确的调用类中的构造器,并将参数传递进去之后,才可以实例化操作。
步骤如下:
1)通过Class类的getDeclaredConstructor(Class... parameterTypes)取得本类的指定形参类型的构造器
2)向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数。
3)通过Constructor实例化对象。

Java
package com.lingstudy.reflection;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;//动态的创建对象,通过反射public class Test09 {public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {//获得Class对象Class c1 = Class.forName("com.mjane.reflection.User");//构造一个对象//User user = (User) c1.newInstance();//本质上是调用了类的无参构造器//System.out.println(user);//User{name='null', id=0, age=0}//通过构造器创建对象//1.获得构造器(User类的有参构造器)//Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);//2.使用构造器创建一个象//User user2 = (User) constructor.newInstance("与世间美好环环相扣", 001, 18);//System.out.println(user2);//User{name='与世间美好环环相扣', id=1, age=18}//通过反射调用普通方法User user3 = (User) c1.newInstance();//通过反射获取一个方法Method setName = c1.getDeclaredMethod("setName", String.class);//invoke :激活// (对象,"方法的值")setName.invoke(user3,"略简");System.out.println(user3.getName());//略简System.out.println("======================");//通过反射操作属性User user4 = (User) c1.newInstance();Field name = c1.getDeclaredField("name");//获取name属性//不能直接操作私有属性,需要关闭程序的安全监测,属性或方法的setAccessible(true);name.setAccessible(true);//设置权限:可以访问name.set(user4,"略简2");System.out.println(user4.getName());//略简2}}


getAnnotations
getAnnotation
要求:利用注解和反射完成类和表结构的映射关系

| id | name | age |
| 001 | 编程之外 | 3 |
| 002 | lingStudy | 18 |
Java
package com.lingstudy.reflection;import java.lang.annotation.*;import java.lang.reflect.Field;//反射操作注解public class Test12 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {Class c1 = Class.forName("com.mjane.reflection.Student2");//通过反射获得注解Annotation[] annotations = c1.getAnnotations();for (Annotation annotation : annotations) {System.out.println(annotation);//@com.mjane.reflection.TableJane(value=db_student)}//获得注解的value的值TableJane tableJane = (TableJane) c1.getAnnotation(TableJane.class);String value = tableJane.value();System.out.println(value);//db_student//获得类指定的注解Field f = c1.getDeclaredField("name");FieldJame annotation = f.getAnnotation(FieldJame.class);System.out.println(annotation.columnName());//db_nameSystem.out.println(annotation.type());//varcharSystem.out.println(annotation.length());//3}}//实体类@TableJane("db_student")class Student2{@FieldJame(columnName = "db_id",type = "int",length = 10)private int id;@FieldJame(columnName = "db_age",type = "int",length = 10)private int age;@FieldJame(columnName = "db_name",type = "varchar",length = 3)private String name;public Student2() {}public Student2(int id, int age, String name) {this.id = id;this.age = age;this.name = name;}public int getId() {return id;}public void setId(int id) {this.id = id;}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;}@Overridepublic String toString() {return "Student2{" +"id=" + id +", age=" + age +", name='" + name + '\'' +'}';}}//类名的注解@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@interface TableJane{String value();}//属性的注解@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@interface FieldJame{String columnName();String type();int length();}






CSDN:与世间美好环环相扣




