本文共 7304 字,大约阅读时间需要 24 分钟。
不是程序本身,可以对程序作出解释
可以被其他程序(比如:解析器等)读取
注解是以“@注释名”在代码重存在的,还可以添加一些参数值
例如:@SuppressWarnings(value=“unchecked”);
可以在package、class、method、field等上面;
表示方法声明旨在覆盖超类型中的方法声明。如果使用此注释类型注释方法,则除非至少满足以下条件之一,否则需要编译器生成错误消息:
该方法将覆盖或实现在超类型中声明的方法。
该方法具有与Object中声明的任何公共方法的 。
注释@Deprecated的程序元素是程序员不鼓励使用的程序元素,通常是因为它是危险的,或者因为存在更好的替代方法。 编译器在不被弃用的代码中使用或覆盖不推荐使用的程序元素时发出警告。
表示在注释元素(以及注释元素中包含的所有程序元素)中应该抑制命名的编译器警告。请注意,给定元素中抑制的一组警告是所有包含元素中抑制的警告的超集。例如,如果您注释一个类来抑制一个警告并注释方法来抑制另一个警告,则两个警告将在该方法中被抑制。
作为一种风格,程序员应该始终将这个注释用于最有效的嵌套元素。 如果要在特定方法中抑制警告,则应该注释该方法而不是其类。
元注解的作用就是赋值注解奇特注解,JAVA定义了4个表中的meta-annotation类型,他们被用来提供对其他annotation类型做说明.
这些类型和它们所支持的类在java.lang.annotation包中可以找到(@Target、@Retention、@Documented、@Inherited)
@Target:用于描述注解的使用范围(即:表示我们的注解可以用在什么地方)
@Retention:表示需要在什么级别保存该注释信息,用于描述注解的生命周期 (即:我们的注解在哪亦然保持效果)
(SOURCE<CLASS<RUNTIME)
@Document:说明该注解将被包含在javadoc中
@Inherited:说明子类可以继承父类中的该注解
1.使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation注解
- 分析
- @interface用来声明一个注解,格式public @interface 注解名{定义内容}
- 其中的每一个方法实际上是声明了一个配置参数
- 方法的名称就是参数的名称
- 返回值类型就是参数的类型(返回值只能是基本类型,class、String、enum)
- 可以通过default来声明参数的默认值
- 如果只有一个参数成员,一般参数名为value
- 注解元素必须要有值,我们定义注解元素时,经常使用空字符串或0作为默认值
/** * @Target 能在什么地方使用:类、接口、方法 * @Retention 能在什么领域使用 */@Target(value{ ElementType.TYPE,ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface MyAnnotation { //MyAnnotation注解名 String value() default""; //value 注解属性名、String注解类型、default注解默认值}
1.反射是java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
2.加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们形象的称之为:反射
反射的优点:
反射的缺点:
反射的作用:
/** * 创建人: 渣高帆 * 创建时间: 2020/6/15 10:54 * JDK 1.8 * 作用:通过反射获取类的Class对象 */public class RefletionTest { public static void main(String[] args) { //创建一个Class对象 Class aClass = null; try { //通过反射获取类的Class对象,一个类只有一个Class对象 //类被加载后整个类的结构都会被封装在Class对象中 aClass = Class.forName("com.zgf.annotation01.entity.Phone"); } catch (ClassNotFoundException e) { e.printStackTrace(); } System.out.println(aClass); }}
- static forName(String name):返回指定类名name的Class对象(完整限定名)
- Object newInstance():调用缺省构造函数,返回Class对象的一个实例
- getName():返回此Class对象所表示的实体(类、接口、数组类或void)的名称。
- Class getSuperClass():返回此Class对象的父类的Class对象
- Class [] getinterfaces():获取当前Class对象的接口
- ClassLoader getClassLoader():返回该类的类加载器
- Constructor [] getConstructors():返回一个包含某些Constructor对象的数组。
- Method getMothed(String name,Class… T):返回一个Method对象,此对象的形参类型为paramType;
- Field [] getDeclaredFields():返回File对象的一个数组
3.类的加载与ClassLoader的理解
/** * 创建人: 渣高帆 * 创建时间: 2020/6/15 10:54 * JDK 1.8 * 作用:通过反射获取类的Class对象,以及获取类中结构 */public class RefletionTest { public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException { //创建一个Class对象 Class aClass = null; try { //通过反射获取类的Class对象,一个类只有一个Class对象 //类被加载后整个类的结构都会被封装在Class对象中 aClass = Class.forName("com.zgf.annotation01.entity.Phone"); } catch (ClassNotFoundException e) { e.printStackTrace(); } //aClass.getName():通过反射获取类的完全限定名 System.out.println(aClass.getName()); //aClass.getSimpleName():通过反射获取类的名字 System.out.println(aClass.getSimpleName()); //aClass.getField(属性名):反射获取单个属性,属性只能是公开的 Field field = aClass.getField("phonename"); System.out.println(field); //aClass.getFields():反射获取多个属性数值,只能获取公开属性 Field[] fields = aClass.getFields(); for (Field fields1 : fields) { System.out.println(fields1); } //aClass.getDeclaredField(属性名):反射获取单个所有访问权限的属性,例如:private、public Field phonename = aClass.getDeclaredField("phonename"); System.out.println(phonename); //aClass.getDeclaredFields():反射获取多个所有访问权限的属性,例如:private、public Field[] declaredFields = aClass.getDeclaredFields(); for (Field declaredFields1 : declaredFields) { System.out.println(declaredFields1); } //aClass.getMethod("方法名"):反射获取类中单个公开的方法,包括基类和父类 Method method = aClass.getMethod("方法名"); //aClass.getMethods():反射获取类中所有公开的方法,包括基类和父类 Method[] methods = aClass.getMethods(); //aClass.getDeclaredMethods():反射获取类中任何访问权限,单个公开的方法,不包括基类和父类 Method declaredMethod = aClass.getDeclaredMethod("方法名"); //aClass.getDeclaredMethods():反射获取类中任何访问权限,所有公开的方法,不包括基类和父类 Method[] declaredMethods = aClass.getDeclaredMethods(); }}
/** * 创建人: 渣高帆 * 创建时间: 2020/6/16 8:56 * JDK 1.8 * 作用:通过反射动态创建对象 */public class RefletionTest01 { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { Class c1 = Class.forName("com.zgf.annotation.entity.User"); //通过反射无参构造来创建一个对象,c1.newInstance()这里获取的是一个构造方法 User user = (User) c1.newInstance(); System.out.println(user); //通过反射有参构造来创建一个对象,getDeclaredConstructor(传入你需要使用构造方法的参数类型) //在Java反射机制中,此方法为暴力获取一个Class文件的私有构造。 Constructor constructor = c1.getDeclaredConstructor(String.class, String.class, String.class); //根据获取的有参构造方法来创建对象并赋予初始值 User user2 = (User) constructor.newInstance("渣高帆", "18", "男"); System.out.println(user2); //反射无参构造创建对象 User user3= (User) c1.newInstance(); //得到一个公开的方法,c1.getDeclaredMethod(方法名,参数类型...); Method method = c1.getDeclaredMethod("setName", String.class); //执行方法, 方法.invoke(对象,传递的参数); method.invoke(user3,"赵盼"); System.out.println(user3); //通过反射获取属性 User user4= (User) c1.newInstance(); //得到一个公开的方法 Field name = c1.getDeclaredField("name"); //关掉权限检查,关掉权限后可以访问任何访问权限修饰的属性,true为关掉、false为开启 name.setAccessible(true); //为当前类属性赋值 name.set(user4,"李黑狗"); System.out.println(name.get(user4)); }}
/** * 创建人: 渣高帆 * 创建时间: 2020/6/16 11:04 * JDK 1.8 * 作用:反射操作注解 */public class RefletionTest02 { public static void main(String[] args) throws ClassNotFoundException { //反射获取Class对象 Class c1 = Class.forName("com.zgf.annotation.entity.User"); //getAnnotation(自定义注解):获取当前Class对象注解信息 DataClass annotation = c1.getAnnotation(DataClass.class); //根据注解的属性名获取值 System.out.println(annotation.name()); }}
//反射获取Class对象 Class c1 = Class.forName("com.zgf.annotation.entity.User"); //getAnnotation(自定义注解):获取当前Class对象注解信息 DataClass annotation = c1.getAnnotation(DataClass.class); //根据注解的属性名获取值 System.out.println(annotation.name()); }}
转载地址:http://omqzi.baihongyu.com/