正常方式: 引入需要的“包类”名称--->通过new实例化---->获得实例化对象
反射方式:实例化对象----->getClass()方法---->得到完整的“包类”名称、
优点:可以实现动态创建对象,灵活性
缺点:对性能有影响
java.lang.Class
java.lang.reflect.Method
java.lang.reflect.Filed
java.lang.reflect.Construtor
public class Test03 { public static void main(String[] args) throws ClassNotFoundException { //通过反射获得类的Class对象 Class c1 = Class.forName("annotation_reflection.user"); System.out.println(c1); Class c2 = Class.forName("annotation_reflection.user"); Class c3 = Class.forName("annotation_reflection.user"); Class c4 = Class.forName("annotation_reflection.user"); //一个类在一个内存中只有一个class对象 //一个类被加载后,类的整个结构都会被封存在class对象中 System.out.println(c2.hashCode()); System.out.println(c3.hashCode()); System.out.println(c4.hashCode()); } } //实体类:pojo entity class user { private String name ; private int id ; private int age; public user() { } public user(String name, int id, int age) { this.name = name; this.id = id; this.age = age; } public String getName() { return name; } public void setName(String name) { 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; } @Override public String toString() { return "user{" + "name='" + name + '\'' + ", id=" + id + ", age=" + age + '}'; } }
public class Test04 { public static void main(String[] args) throws ClassNotFoundException { Person person = new Student(); System.out.println("这个人的姓名是:"+ person.getName()); //1.通过对象获得 Class c1 = person.getClass(); System.out.println(c1.hashCode()); //2.forname获得 Class c2 = Class.forName("annotation_reflection.Person"); System.out.println(c2.hashCode()); //3.通过类名.class获得 Class c3 = Student.class; System.out.println(c3.hashCode()); //4.基本的内置类型的包装类都有一个Type属性 Class c4 = Integer.TYPE; System.out.println(c4); //获得父类类型 Class c5 = c1.getSuperclass(); System.out.println(c5); } } class Person{ private String name; public Person() { } public Person(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "person{" + "name='" + name + '\'' + '}'; } } class Student extends Person{ public Student(){ this.setName("学生"); } } class Teacher extends Person{ public Teacher(){ this.setName("老师"); } }
public class Test05 { public static void main(String[] args) { Class c1 = Object.class;//类 Class c2 = Comparable.class;//接口 Class c3 = String[].class;//一维数组 Class c4 = int[][].class;//二维数组 Class c5 = Override.class;//注解 Class c6 = ElementType.class;//枚举 Class c7 = Integer.class;//基本数据类型 Class c8 = void.class;//void Class c9 = Class.class;//Class System.out.println(c1); System.out.println(c2); System.out.println(c3); System.out.println(c4); System.out.println(c5); System.out.println(c6); System.out.println(c7); System.out.println(c8); System.out.println(c9); } } 类的加载与ClassLoader的理解
加载--->链接----->初始化
public class Test06 { public static void main(String[] args) { A a = new A(); System.out.println(A.m); } } class A{ static { System.out.println("A类静态代码初始化"); Object m; m = 300; } // m = 300; // m = 100; static int m = 100; public A(){ System.out.println("A类的无参构造初始化"); } }
1.加载到内存,会产生一个Class的对象
2.链接,链接结束后m=0
3.初始化
类的初始化
类的主动引用(一定会发生类的初始化)
类的被动引用(不会发生类的初始化)
public class Test07 { static { System.out.println("Main类被加载"); } public static void main(String[] args) throws ClassNotFoundException { //1.主动引用 Son son = new Son(); //反射也会产生主动引用 // Class.forName("annotation_reflection.Son"); //不会产生类的引用的方法 System.out.println(Son.b);//用子类去调父类的静态方法或者静态变量并不会让子类进行加载 //Son[] array= new Son[5]; System.out.println(Son.M); //常量在链接阶段就存入了调用类的常量池中了 } } class Father { static int b = 2; static { System.out.println("父类被加载"); } } class Son extends Father { static { System.out.println("子类被加载"); Object m; m = 300; } static int m =100; static final int M =1; 类加载器
类加载器的作用
引导类加载器:负责java平台核心库
扩展类加载器
系统类加载器
系统类的加载器---->扩展类加载器---->根加载器(爷爷)
public class Test08 { public static void main(String[] args) throws ClassNotFoundException { //获取系统类的加载器 ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); System.out.println(systemClassLoader);//$AppClassLoader //获取系统类加载器的父类加载器---->扩展类加载器 ClassLoader parent = systemClassLoader.getParent(); System.out.println(parent);//$PlatformClassLoader //获取扩展类加载器的父类加载器---->根加载器(c/c++) ClassLoader parent1 = parent.getParent(); System.out.println(parent1);//null //测试当前类是哪个加载器加载的 ClassLoader classLoader = Class.forName("annotation_reflection.Test08").getClassLoader(); System.out.println(classLoader);//$AppClassLoader //测试JDK内置的类是谁加载的 classLoader = Class.forName("java.lang.Object").getClassLoader(); System.out.println(classLoader);//null //如何获取系统类加载器可以加载的路径 System.out.println(System.getProperty("java.class.path")); //双亲委派机制(多重检测,保证安全性) //java.lang.String---> } } 创建运行时类的对象public class Test09 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException,NoSuchFieldException { Class<?> c1 = Class.forName("annotation_reflection.user"); //获取类的名字 System.out.println(c1.getName());//获得包名+类名 System.out.println(c1.getSimpleName());//获得类名 System.out.println("====================================="); //获得类的属性 Field[] fields = c1.getFields(); //只能找到public属性 fields = c1.getDeclaredFields();//可以找到全部属性 name id age for (Field field : fields) { System.out.println(field); } System.out.println("======================================"); //获得指定属性的值 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("getDeclaredMethods:"+method); } //获得指定方法 Method getName = c1.getMethod("getName",null); Method setName = c1.getMethod("setName", String.class); System.out.println(getName); System.out.println(setName); //获得指定的构造器 Constructor[] constructors = c1.getConstructors();//获得本类及其父类的全部public方法 for (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); } }
也可以通过调用Calss对象的newInstance()的方法来创建类的对象
1.类必须要有一个无参的构造器
2.类的无参构造器访问权限要足够
//动态的创建对象,通过反射 public class Test010 { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { //获得class对象 Class c1 = Class.forName("annotation_reflection.User"); //构造一个对象 //User user = (User) c1.newInstance();//本质是调用类的无参构造器 //System.out.println(user); //通过构造器获取对象 Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class); User user1 = (User) constructor.newInstance("xxx",18,18); System.out.println(user1); //通过反射调用普通方法 User user2 = (User) c1.newInstance(); //通过反射获取方法 Method setName = c1.getDeclaredMethod("setName", String.class);//(对象,“方法的值) //invoke:激活的意思 setName.invoke(user2,"zmm");(对象,方法的值) System.out.println(user2.getName()); //通过反射操作熟悉 User user3 = (User) c1.newInstance(); Field name = c1.getDeclaredField("name");//getDeclaredField获取指定属性 System.out.println(name);//(private java.lang.String annotation_reflection.User.name) //不能直接操作私有属性,我们需要关闭程序的安全检测,通过属性或者方法的setAccessible(true) name.setAccessible(true);// name.set(user3,"zmm2"); System.out.println(user3.getName()); } } setAccessible
分析性能问题
//分析性能问题 public class Test011 { //普通方法调用 public static void test01(){ User user = new User(); long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { user.getName(); } long endTime = System.currentTimeMillis(); System.out.println("普通方式执行10亿次:"+(endTime-startTime)+"ms");//3ms } //反射方法调用 public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { User user = new User(); Class c1 = user.getClass(); Method getName = c1.getDeclaredMethod("getName",null); long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { getName.invoke(user,null); } long endTime = System.currentTimeMillis(); System.out.println("反射方式执行10亿次:" + (endTime - startTime) + "ms");//1953ms } //反射方法调用,关闭检测 public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { User user = new User(); Class c1 = user.getClass(); Method getName = c1.getDeclaredMethod("getName",null); getName.setAccessible(true); long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { getName.invoke(user,null); } long endTime = System.currentTimeMillis(); System.out.println("关闭检测后执行10亿次:" + (endTime - startTime) + "ms");//1159ms } public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { test01(); test02(); test03(); } }
反射操作泛型
generic:泛型
public class Test012 { public void test01(Map<String, User> map, List<User> list) { System.out.println("test01"); } public Map<String, User> test02() { System.out.println("test02"); return null; } public static void main(String[] args) throws NoSuchMethodException { 先获取方法 Method method = Test012.class.getMethod("test01", Map.class, List.class); 获取方法的参数化类型 Type[] genericParameterTypes = method.getGenericParameterTypes(); for (Type genericParameterType : genericParameterTypes) { System.out.println("#" + genericParameterType); if (genericParameterType instanceof ParameterizedType){ Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments(); for(Type actualTypeArgument : actualTypeArguments){ System.out.println(actualTypeArgument); } } } method = Test012.class.getMethod("test02"); 返回值泛型的参数类型 Type genericReturnType = method.getGenericReturnType(); if (genericReturnType instanceof ParameterizedType){ Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments(); for(Type actualTypeArgument : actualTypeArguments){ System.out.println(actualTypeArgument); } } } }
反射操作注解
ORM:
public class Test013 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { Class<?> c1 = Class.forName("annotation_reflection.Student2"); //通过反射获得注解 Annotation[] annotations = c1.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation); } //通过反射获得注解得的值 Tablezmm tablezmm = (Tablezmm) c1.getAnnotation(Tablezmm.class); String value = tablezmm.value(); System.out.println(value); //获得类指定的注解 Field name = c1.getDeclaredField("name"); Fieldzmm annotation = name.getAnnotation(Fieldzmm.class); System.out.println(annotation.columnName()); System.out.println(annotation.type()); System.out.println(annotation.length()); } } @Tablezmm("db_student") class Student2{ @Fieldzmm(columnName = "db_id",type = "int",length = 10) private int id; @Fieldzmm(columnName = "db_age",type = "int",length = 10) private int age; @Fieldzmm(columnName = "db_name",type = "varchar",length = 4) 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; } @Override public String toString() { return "Student2{" + "id=" + id + ", age=" + age + ", name='" + name + '\'' + '}'; } } //类名的注解 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface Tablezmm{ String value(); } //属性的注解 @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @interface Fieldzmm{ String columnName(); String type(); int length(); }
个人学习笔记,并不是很全,跟着视频自学的,可能存在错误,仅供参考。