package sixDay.ReflectZhuJie;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//只允许该注解可以标注类,方法
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
//希望这个注解可以被反射
@Retention(RetentionPolicy.RUNTIME)
//如果写的是SOURCE,则是注解只保留在源文件中,,如果是CLASS,则注解保存在class文件中
//如果是RUNTIME,则不仅保存在class文件中,同时也可以被反射机制读到
public @interface ReflectZhuJieTest01 {
String value() default "是哦七日内";
}
package sixDay.ReflectZhuJie;
public class ReflectZhuJieTest02 {
int i;
public static void main(String[] args) {
Class lei;
{
try {
lei = Class.forName("sixDay.ReflectZhuJie.ReflectZhuJieTest03");
//isAnnotationPresent判断有没有当下括号里的注解,这个判断是判断类上面是不是有这个注解,不是判断类里面有没有注解
System.out.println("----------");
System.out.println(lei.isAnnotationPresent(ReflectZhuJieTest01.class));
//有注解,获取这个注解
if(lei.isAnnotationPresent(ReflectZhuJieTest01.class)){
//获取该注解对象
ReflectZhuJieTest01 reflectZhuJieTest01 =
(ReflectZhuJieTest01) lei.getAnnotation(ReflectZhuJieTest01.class);
System.out.println("类的注解对象 :" + reflectZhuJieTest01);
//调用属性
System.out.println(reflectZhuJieTest01.value());
}
Class string = Class.forName("java.lang.String");
System.out.println(string.isAnnotation());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
package sixDay.ReflectZhuJie;
import sixDay.ReflectZhuJie.ReflectZhuJieTest01;
@ReflectZhuJieTest01
public class ReflectZhuJieTest03 {
@ReflectZhuJieTest01
public void doSome(){
}
}
======================
package sixDay.ZhuJieShuXing;
import sixDay.Season;
public @interface ZhuJieShuXing {
/**
* 我们通常在注解中可以定义属性:以下这个是ZhuJieShuXingTest的属性
* 注解中的属性可以是哪些类型?
* byte,short,int,long,float,double,boolean,char,Class,String,枚举
* 以及以上的数组类型形式。
*/
int[] value2();
String[] aa();
Season value1();
Season value3(); //这个value3怎么不一样
Class parameter();
Class[] parameters();
//当属性是value时
String value();
String name();
String color();
//有默认值,则注解时可不再赋值
int age() default 21;
}
package sixDay.ZhuJieShuXing;
import sixDay.Season;
public @interface ZhuJieShuXing02 {
String[] email();
Season[] season();
}
package sixDay.ZhuJieShuXing;
public class ZhuJieShuXingTest {
/**
* 保错原因:如果一个注解中有属性,那么必须给属性赋值,除非该属性使用default指定了默认值
* 'name' missing though required
* 缺少“名称”,但必填
*
* @ZhuJieShuXing()
* public void doSome(){}
*/
//@ZhuJieShuXing(name = "mm",color = "blue",value = "heeh")
public void doSome2(){
}
//value无论放在前面,还是放在后面都不能省略
// @ZhuJieShuXing(value = "sfd",name = "ss",color = "blue")
public void doOther(){
}
/**
* 当只有一个value时可以省略value =
* @ZhuJieShuXing(value = "sdsdfs")
* public void doOter2(){}
*
* @ZhuJieShuXing("sdf")
* public void doSome2(){}
*/
}
package sixDay.ZhuJieShuXing;
import sixDay.Season;
import sixDay.ZhuJieShuXing.ZhuJieShuXing02;
public class ZhuJieShuXingTest02 {
//里面是数组时,元素为多个时,要加上大括号
@ZhuJieShuXing02(email = {
"sdfsdf","dsfsgvf"},season = {
Season.AUTUMN,Season.SPRING})
public void doSome(){
}
//数组元素只有一个时,括号可以省略
@ZhuJieShuXing02(email = "dsfssa",season = Season.WINTER)
public void doOther(){
}
}
=========================
package sixDay.ZhuJieXinXIGet;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class MyAnnotationTest {
@MyAnnotation(name = "sfd",password = "23d34gfd43")
public void doSome(){
}
/**
* 怎样获得方法上注解里的属性
* 1、获取这个类
* Class.forName()
* 2、获取这个类的方法
* lei.getDeclaredMethod("");
* 3、判断这个方法是否是注解方法
* if(方法.isAnnotationMethod(MyAnnotation.class))
* 4、建一个注解对象 MyAnnotation ss = 方法.getAnnotation(MyAnnotation.class)
* sout(ss.name())
*/
public static void main(String[] args) {
//首先获取这个类
Class lei = null;
try {
lei = Class.forName("sixDay.ZhuJieXinXIGet.MyAnnotationTest");
//获取这个类的方法
Method doSomeMethod = lei.getDeclaredMethod("doSome");
//判断这个方法上是否存在注解(不能直接获取注解方法)
if(doSomeMethod.isAnnotationPresent(MyAnnotation.class)){
//存在注解的话,获取这个对象
MyAnnotation myAnnotation = doSomeMethod.getAnnotation(MyAnnotation.class);
System.out.println(myAnnotation.name());
System.out.println(myAnnotation.password());
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
package sixDay.ZhuJieXinXIGet;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//允许该注解可以被反射
@Retention(RetentionPolicy.RUNTIME)
//只允许该注解标注方法,文件(变量),类
@Target({
ElementType.METHOD,ElementType.FIELD,ElementType.TYPE})
public @interface MyAnnotation {
String name();
String password();
}
==========================
package sixDay.ZhuJieXuQiu;
//自定义异常
public class HasNotException extends Exception{
// 无参
public HasNotException() {
}
public HasNotException(String s) {
super(s);
}
}
package sixDay.ZhuJieXuQiu;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({
ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})
public @interface MyAnnotation {
}
package sixDay.ZhuJieXuQiu;
import java.lang.reflect.Field;
public class MyAnnotationTest {
public static void main(String[] args) {
try {
//获取类
Class lei = Class.forName("sixDay.ZhuJieXuQiu.Student");
//获取属性
Field[] fields = lei.getDeclaredFields();
//做个标记,用变量自加的方法,不如打个标记方便
//int i = fields.length;
//int count = 0;
boolean isOk = false;
//判断注释和数据类型,直接判断
for(Field field : fields){
//field.getAnnotatedType().isAnnotationPresent(MyAnnotation.class)这个注解就是
/*if(field.getAnnotatedType().isAnnotationPresent(MyAnnotation.class) &&
"int".equals(field.getType().getSimpleName())){*/
if("id".equals(field.getName())&&
"int".equals(field.getType().getSimpleName())){
isOk = true;
break;
}
//count++;
}
if(isOk != true){
throw new HasNotException("被@MyAnnotation注解的类中必须要有一个int类型的id属性");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (HasNotException e) {
e.printStackTrace();
}
}
}
package sixDay.ZhuJieXuQiu;
@MyAnnotation
public class Student {
int id;
String name;
String password;
}
===============================
package sixDay;
@Deprecated
public class DeprecatedTest {
public static void main(String[] args) {
DeprecatedTest deprecated = new DeprecatedTest();
//本类调用没有横线显示
deprecated.doSome();
}
@Deprecated
public int i;
@Deprecated
public void doSome(){
}
public DeprecatedTest(){
}
}
//这个注解主要是向其他程序员传达一个信息,告知已过时,有更好的解决方案存在
class MyTest{
public static void main(String[] args) {
DeprecatedTest deprecatedTest = new DeprecatedTest();
//别的类调用时会有横线显示,本类调用的话没有横线显示
deprecatedTest.doSome();
deprecatedTest.i = 12;
try {
Class c = Class.forName("java.lang.String");
Object obj = c.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
package sixDay;
@MyAnnotation
public class MyAnnotationTest {
private int age;
@MyAnnotation
public MyAnnotationTest(int age) {
this.age = age;
}
public void doSome(@MyAnnotation String name,@MyAnnotation int age){
@MyAnnotation
int i = 1;
}
}
@MyAnnotation
interface MyInterface{
}
package sixDay;
/**
* 1、注解,或叫做注释,英文单词Annotation
*
* 2、注解Annotation是一种引用数据类型,编译之后也是生成***.class文件
*
* 3、定义注解:
* 【修饰符列表】 @interface 注解类型名
*
* 4、怎么用?用在什么地方?
* 1、使用时的语法格式:@注解类型名
*
* 2、注解可以出现在类上,属性上,方法上,变量上。。。
* 注解还可以出现在注解类型上
*
* 5、JDk有哪些注解:
*
* 掌握
* Deprecated 用@Deprecated注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险
* 或者存在更好的选择
*
* 掌握
* Override 表示一个方法声明打算重写超类中的另一个方法声明
*
* 不用掌握
* SuppressWarnings
* 指示在注释元素(和包含在注释元素中的所有程序元素中)应被抑制命名的编译器警告
*
* 6、元注解
* :用来标注”注解类型“的”注解“,称为元注解
*
* 常见的元注解:
* Target
* Retention
*
* Target:
* 这是一个元注解,用来标注“注解类型”的“注解”
* 用来标注“被标注的注解”可以出现在哪些位置上
*
* @Target(ElementType.METHOD) 表示“被标注的注解”只能出现在方法上
*
* Retention
* 用来标注“注解类型”的“注解”,标注“被标注的注解”最终保存在哪里
* @Retention(RetentionPolicy.SOURCE) 表示该注解只被保留在java源文件中
* @Retention(RetentionPolicy.CLASS) 表示该注解被保存在class文件中
* @Retention(RetentionPolicy.RUNTIME) 表示该注解被保存在class文件中,并且可以被反射机制所读取
*
* 元注解
* public @interface Retention {
* 属性
* RetentionPolicy value();
* }
*
* RetentionPolicy的源代码
* public enum RetentionPolicy {
*
* SOURCE,
* CLASS,
* RUNTIME
* }
*
* @Retention (value = RetentionPolicy.RUNTIME)
* 省略value @Retention (RetentionPolicy.RUNTIME)
* public @interface MyAnnotation{}
*
* 7、注解在开发中有什么用?
* 需求:
* 假设有这样一个注解:@id
* 这个注解只能出现在类上面,叫这个类上有这个注解的时候
* 要求这个类中必须有一个int类型的id属性,如果没有这个属性就报异常,如果有这个属性则正常执行
*
*
*
*/
public class Note {
}
package sixDay;
/**
* 关于JDK lang包下的Override注解
*
* public @interface Override {
* }
*
* @Override 这个注解只能注解方法
* 这个注解是给编译器参考的,和运行阶段没有关系
* 凡是java中的方法带有这个注解的,编译器会进行编译检查,如果这个方法不是重写父类的方法,编译器报错
*
* 标识性注解,给编译器作参考的(编译阶段起作用,和运行阶段无关)
* 编译器看到方法上有这个注解的时候,编译器会自动检查方法是否重写了父类方法
*/
public class OverrideTest {
/*@Override
public String toString(){
return toString;
}
*/
}
package sixDay;
public enum Season {
SPRING,SUMMER,AUTUMN,WINTER
}