java 基础注解和反射(完结)

本贴最后更新于 1616 天前,其中的信息可能已经时移世改

四个元注解

image.png

package net.yscxy.annoction; import java.lang.annotation.*; /** * @Author WangFuKun * @create 2020/12/4 20:20 */ //测试元注解 public class Test02 { @MyAnotation public void test() { } } //定义一个注解 //Target表示我们的注解可以用在哪些地方 //Retention表示我们的注解在什么时候还有效runtime>class>source //Documented表示是否将我们的注解生成在javadoc中 //Inherited子类可以继承父类 @Target(value = {ElementType.METHOD, ElementType.TYPE}) @Retention(value = RetentionPolicy.RUNTIME) @Documented() @Inherited() @interface MyAnotation { }

Target 表示我们的注解可以用在哪些地方
Retention 表示我们的注解在什么时候还有效 runtime>class>source
Documented 表示是否将我们的注解生成在 javadoc 中
Inherited 子类可以继承父类

如何自定义注解

image.png

package net.yscxy.annoction; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Test; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @Author WangFuKun * @create 2020/12/4 21:30 */ //自定义注解 public class Test03 { @Test @MyAnnotation2(name = "wfk", age = 10) public void test() { } } @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation2 { //注解的参数:参数类型+参数名(); String name() default ""; int age(); int id() default -1;//如果默认值为-1,代表不存在,如果找不到就返回-1 String[] schools() default {"清华大学", }; }

反射机制

静态语言 VS 动态语言

image.png

Java Reflection

image.png

image.png

获取 Class 类的实例的几种方案

image.png

package net.yscxy.reflection; /** * @Author 野生程序员 http://yscxy.net/ * @create 2020/12/5 10:29 */ public class Test03 { public static void main(String[] args) throws ClassNotFoundException { Person person = new Student(); System.out.println("这个人是->" + person.name); //方式一:通过对象获得 Class c1 = person.getClass(); System.out.println(c1); //方式二:forname获得 Class c2 = Class.forName("net.yscxy.reflection.Student"); System.out.println(c2); //方式三:通过类名.class获得 Class c3 = Student.class; System.out.println(c3); //方式四:基本内置类型的包装类都有一个Type属性 Class c4 = Integer.TYPE; System.out.println(c4); //获得父类类型 Class c5 = c1.getSuperclass(); System.out.println(c5); } } class Person { String name; public Person() { } public Person(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; } } class Student extends Person { public Student() { this.name = "学生"; } } class Teacher extends Person { public Teacher() { this.name = "老师"; } }

代码二

package net.yscxy.reflection; import java.lang.annotation.ElementType; /** * @Author 野生程序员 http://yscxy.net/ * @create 2020/12/5 10:46 */ //所有类的class public class Test04 { 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); } }
什么时候会发生类的初始化

image.png

package net.yscxy.reflection; /** * @Author 野生程序员 http://yscxy.net/ * @create 2020/12/5 11:10 */ public class Test06 { static { System.out.println("main类被加载..."); } public static void main(String[] args) throws ClassNotFoundException { //1.主动引用 //Son son = new Son(); //反射也会产生主动引用引用 //Class.forName("net.yscxy.reflection.Son"); //不会产生类的引用的方法 //System.out.println(Son.b); //Son[] arr = 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("子类被加载..."); } static int m = 100; static final int M = 1; }
类加载器的作用

image.png

获取类的方法、字段、构造器、等等
package net.yscxy.reflection; import java.io.File; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; /** * @Author 野生程序员 http://yscxy.net/ * @create 2020/12/5 15:49 */ public class Test08 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException { Class c1 = Class.forName("net.yscxy.reflection.User"); //获得类的名字 System.out.println(c1.getName()); System.out.println(c1.getSimpleName()); //获得类的属性 Field[] fields = c1.getFields();//只能找到public属性 for (int i = 0; i < fields.length; i++) { System.out.println(fields[i]); } Field name = c1.getDeclaredField("name"); System.out.println(name); //获得类的方法 System.out.println("=======================获得类的方法========================="); Arrays.asList(c1.getMethods()).forEach(System.out::println);//获得本类以及父类的全部public方法 System.out.println("=======================获得本类的所有方法========================="); Arrays.asList(c1.getDeclaredMethods()).forEach(System.out::println);//获得本类的所有方法 //获得指定方法 System.out.println("获得指定方法"); Method getName = c1.getMethod("getName", null); Method getAge = c1.getMethod("getAge", null); System.out.println(getName); System.out.println(getAge); System.out.println("获得指定的构造器"); Constructor[] constructors = c1.getConstructors(); Arrays.asList(constructors).forEach(System.out::println); System.out.println("+++++++++++"); Arrays.asList(c1.getDeclaredConstructors()).forEach(System.out::println); System.out.println("获得指定的构造器"); Constructor declaredConstructor = c1.getDeclaredConstructor(int.class, String.class, int.class); System.out.println("指定:" + declaredConstructor); } }
通过反射动态创建对象

image.png

package net.yscxy.reflection; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @Author 野生程序员 http://yscxy.net/ * @create 2020/12/6 8:43 */ //通过反射动态创建对象 public class Test09 { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { Class<?> c1 = Class.forName("net.yscxy.reflection.User"); //构造对象 User user = (User) c1.newInstance(); System.out.println(user); //通过构造器创建对象 Constructor<?> declaredConstructor = c1.getDeclaredConstructor(int.class, String.class, int.class); User user13 = (User) declaredConstructor.newInstance(1, "测试", 1); System.out.println(user13); //通过反射获取一个方法,invoke激活的意思 User user3 = (User) c1.newInstance(); Method setName = c1.getDeclaredMethod("setName", String.class); setName.invoke(user3, "野生程序员"); System.out.println(user3); //通过反射操作属性 User user4 = (User) c1.newInstance(); Field name = c1.getDeclaredField("name"); //设置属性是否可以被访问,也就是取消他的安全监测,不能直接访问私有属性,只有关掉之后才能访问 name.setAccessible(true); name.set(user4, "野生程序员2"); System.out.println(user4); } }
三种方式的额性能检测
package net.yscxy.reflection; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @Author 野生程序员 http://yscxy.net/ * @create 2020/12/7 16:07 */ //分析反射性能问题 public class Test10 { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { test01(); test02(); test3(); } //普通方式调用 public static void test01() { User user = new User(); long starTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { user.getName(); } long endTime = System.currentTimeMillis(); System.out.println("普通方式耗费时间->" + (endTime - starTime)); } //反射方式调用 public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { User user = new User(); Class c1 = user.getClass(); Method getName = c1.getDeclaredMethod("getName", null); long starTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { getName.invoke(user, null); } long endTime = System.currentTimeMillis(); System.out.println("反射方式耗费时间->" + (endTime - starTime)); } //反射方式调用 并且关闭安全检测 public static void test3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { User user = new User(); Class c1 = user.getClass(); Method getName = c1.getDeclaredMethod("getName", null); getName.setAccessible(true); long starTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { getName.invoke(user, null); } long endTime = System.currentTimeMillis(); System.out.println("反射并且关闭安全检查方式耗费时间->" + (endTime - starTime)); } }

运行结果

普通方式耗费时间->5
反射方式耗费时间->4928
反射并且关闭安全检查方式耗费时间->2171

通过反射操作泛型

image.png

package net.yscxy.reflection; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.Map; /** * @Author 野生程序员 http://yscxy.net/ * @create 2020/12/7 16:24 */ //通过反射获取泛型 public class Test11 { 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 = Test11.class.getMethod("test01", Map.class, List.class); Type[] genericExceptionTypes = method.getGenericParameterTypes(); for (Type ge : genericExceptionTypes) { System.out.println(ge); //instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例 if (ge instanceof ParameterizedType) { System.out.println("开始打印..."); Type[] actualTypeArguments = ((ParameterizedType) ge).getActualTypeArguments(); for (Type actualTypeArgument : actualTypeArguments) { System.out.println(actualTypeArgument); } } } System.out.println("获取返回值的泛型的参数类型..."); method = Test11.class.getMethod("test02", null); Type genericReturnType = method.getGenericReturnType(); System.out.println(genericReturnType); if (genericReturnType instanceof ParameterizedType) { Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments(); for (Type actualTypeArgument : actualTypeArguments) { System.out.println(actualTypeArgument); } } } }

运行结果

java.util.Map<java.lang.String, net.yscxy.reflection.User>
开始打印...
class java.lang.String
class net.yscxy.reflection.User
java.util.List<net.yscxy.reflection.User>
开始打印...
class net.yscxy.reflection.User
获取返回值的泛型的参数类型...
java.util.Map<java.lang.String, net.yscxy.reflection.User>
class java.lang.String
class net.yscxy.reflection.User

反射操作注解

了解一下什么叫 ORM

image.png

package net.yscxy.reflection; import java.lang.annotation.*; import java.lang.reflect.Field; /** * @Author 野生程序员 http://yscxy.net/ * @create 2020/12/7 16:59 */ public class Test12 { public static void main(String[] args) throws NoSuchFieldException { Class c1 = Student2.class; //通过反射获取注解 Annotation[] annotations = c1.getAnnotations(); for (Annotation a : annotations) { System.out.println(a); } //获取注解的value的值 TableY tableY = (TableY) c1.getAnnotation(TableY.class); System.out.println(tableY.value()); //获得类指定的注解 Field f = c1.getDeclaredField("name"); FiledY annotation = f.getAnnotation(FiledY.class); System.out.println(annotation.columnName()); System.out.println(annotation.type()); System.out.println(annotation.length()); } } //数据 @TableY("du_student") class Student2 { @FiledY(columnName = "db_id", type = "int", length = 10) private int id; @FiledY(columnName = "db_age", type = "int", length = 10) private int age; @FiledY(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; } @Override public String toString() { return "Student2{" + "id=" + id + ", age=" + age + ", name='" + name + '\'' + '}'; } } //类名注解 @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @interface TableY { String value(); } //属性的注解 @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @interface FiledY { String columnName(); String type(); int length(); }

运行结果

@net.yscxy.reflection.TableY(value=du_student)
du_student
db_name
carchar
3

  • 反射和注解
    1 引用
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3201 引用 • 8216 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...