Day17-注解与反射
2021/6/18 6:03:22
本文主要是介绍Day17-注解与反射,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
注解与反射
注解
可被其他程序(如:编译器)读取,可以对程序做出解释
以@注释名在代码中存在
内置注解
@Override
必须重写父类存在的方法,否则报错
@Deprecated
表示不鼓励使用该类或者方法或者属性
@SuppressWarnings(“xxx”)
抑制编译时的警告信息
元注解
用于注解其他注解的注解
@Target(value={})
约束其他注解可以使用的地方
@Retention
表示注解在什么地方还有效,一般写runtime
runtime>class>sources
@Documented
表示是否将注解生成在Javadoc中
@inherited
子类可以继承父类的注解
自定义注解
通过@interface 注解名{}来定义注解
参数类型+参数名+()来定义参数
@Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @interface MyInterface{ String name() default ""; //如果不设置默认值,则必须填写 int age(); } @Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @interface MyInterface1{ String value(); //当只有一个参数,且参数名为value时,可以省略参数名 } @MyInterface(age = 18) public static void test1(){} @MyInterface1("") public static void test2(){}
反射
Java被视为动态语言的关键,反射机制允许程序在执行期间借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性和方法
优点
可以实现动态创建对象和编译,体现很大的灵活性
缺点
影响性能
Class类
只能由系统创建,反射可以获取class类的对象, 在jvm中有且只有一个实例
package Reflection; public class Test01 { public static void main(String[] args) throws ClassNotFoundException { Person person = new Student(); //Class类的创建方法 //方式一:通过对象获得 Class c1 = person.getClass(); //方式二:通过完整的类名获得 Class c2 = Class.forName("Reflection.Student"); //方式三:通过类名.class获得 Class c3 = Student.class; //基本内置类都会有一个type属性 Class c4 = Integer.TYPE; System.out.println(c1.hashCode()); System.out.println(c2.hashCode()); System.out.println(c3.hashCode()); System.out.println(c4.hashCode()); } } class Person{ public String name; public int age; public Person() { } } class Student extends Person{ public Student() { this.name = "学生"; } } class Teacher extends Person{ public Teacher(){ this.name = "老师"; } }
通过反射获取类的信息
package Reflection; import java.lang.reflect.Field; import java.lang.reflect.Method; //获取类的信息 public class Test02 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException { User user = new User(); Class c1 = user.getClass(); //获得类的名字 System.out.println(c1.getName()); //获得类名+包名 System.out.println(c1.getSimpleName()); //获得类名 //获得类的属性 Field[] fields = c1.getFields(); //获取方法中的公共属性 fields =c1.getDeclaredFields(); //获取方法中的所有属性 for(Field field:fields){ System.out.println(field); } //获得类的方法 Method[] method = c1.getMethods(); //获得子类和父类的所有方法 method = c1.getDeclaredMethods(); //获得本类的所有方法 for(Method method1:method){ System.out.println(method1); } System.out.println("**********************"); Method method1 = c1.getMethod("getName",null); //获取指定的方法 System.out.println(method1); //获取构造器,方法同上。。。 } }
通过反射动态创建对象
package Reflection; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; //通过反射动态地创建对象 public class Test03 { public static void main(String[] args) throws Exception { Class c1 = Class.forName("Reflection.User"); //方式一 Object o = c1.newInstance(); //该类必须有无参构造器 //方式二 Constructor constructor = c1.getConstructor(String.class,int.class,int.class); User user = (User)constructor.newInstance("chenchenchen",18,1); System.out.println(user); //调用对象中的方法 Method setName = c1.getMethod("setName", String.class); setName.invoke(user,"陈琛琛"); System.out.println(user.getName()); //调用对象中的属性 Field name = c1.getDeclaredField("name"); name.setAccessible(true); //设置是否开启权限 name.set(user,"haha"); System.out.println(user.getName()); } }
性能对比
package Reflection; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; //通过反射动态地创建对象 public class Test03 { public static void main(String[] args) throws Exception { Class c1 = Class.forName("Reflection.User"); //方式一 Object o = c1.newInstance(); //该类必须有无参构造器 //方式二 Constructor constructor = c1.getConstructor(String.class,int.class,int.class); User user = (User)constructor.newInstance("chenchenchen",18,1); System.out.println(user); //调用对象中的方法 Method setName = c1.getMethod("setName", String.class); setName.invoke(user,"陈琛琛"); System.out.println(user.getName()); //调用对象中的属性 Field name = c1.getDeclaredField("name"); name.setAccessible(true); //设置是否开启权限 name.set(user,"haha"); System.out.println(user.getName()); } }
泛型类型
package Reflection; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.Map; //获取泛型的真实类型 public class Test05 { public static void test1(Map<String,User> map, List<String> list){ System.out.println("test1"); } public Map<String,User> test2(){ System.out.println("test2"); return null; } public static void main(String[] args) throws NoSuchMethodException { Method method = Test05.class.getMethod("test1", Map.class, List.class); Type[] genericParameterTypes = method.getGenericParameterTypes(); //获得泛型的参数类型数组 for (Type genericParameterType : genericParameterTypes) { //打印类型 if(genericParameterType instanceof ParameterizedType){ //如果是参数化类型,将其进行强制转换,然后调用方法获取真实参数类型 Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments(); for (Type actualTypeArgument : actualTypeArguments) { //打印真实类型 System.out.println(actualTypeArgument); } } } method = Test05.class.getMethod("test2"); Type genericReturnType = method.getGenericReturnType(); if(genericReturnType instanceof ParameterizedType){ Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments(); for (Type actualTypeArgument : actualTypeArguments) { System.out.println(actualTypeArgument); } } } }
ORM
package Reflection; import java.lang.annotation.*; import java.lang.reflect.Field; public class ORM { public static void main(String[] args) throws NoSuchFieldException { Final f = new Final(); Class c1 = f.getClass(); Annotation annotation = c1.getAnnotation(Table.class); System.out.println(annotation); //获取注解中的数据 Table table = (Table)annotation; System.out.println(table.value()); Field name = c1.getDeclaredField("id"); //属性的注解需要先获取到属性值 name.setAccessible(true); TableTest annotation1 = name.getAnnotation(TableTest.class); System.out.println(annotation1.tableName()); System.out.println(annotation1.type()); System.out.println(annotation1.length()); } } @Table("db_Test") class Final{ @TableTest(tableName = "Test",type = "String",length = 10) private String name; @TableTest(tableName = "Test",type = "int",length = 2) private int age; @TableTest(tableName = "Test",type = "int",length = 10) private int id; public Final() { } public Final(String name, int age, int id) { this.name = name; this.age = age; this.id = id; } @Override public String toString() { return "Final{" + "name='" + name + '\'' + ", age=" + age + ", id=" + id + '}'; } } //类名注解 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface Table{ String value(); //表名 } //属性的注解 @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @interface TableTest{ String tableName(); String type(); int length(); }
这篇关于Day17-注解与反射的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26Mybatis官方生成器资料详解与应用教程
- 2024-11-26Mybatis一级缓存资料详解与实战教程
- 2024-11-26Mybatis一级缓存资料详解:新手快速入门
- 2024-11-26SpringBoot3+JDK17搭建后端资料详尽教程
- 2024-11-26Springboot单体架构搭建资料:新手入门教程
- 2024-11-26Springboot单体架构搭建资料详解与实战教程
- 2024-11-26Springboot框架资料:新手入门教程
- 2024-11-26Springboot企业级开发资料入门教程
- 2024-11-26SpringBoot企业级开发资料详解与实战教程
- 2024-11-26Springboot微服务资料:新手入门全攻略