01. 单元测试的基本使用
/*
单元测试用于替换程序中的main方法, 程序可以从单元测试方法开始执行。
如果在一个方法上加上了@Test注解,那么这个方法就是单元测试方法了,程序可以从这个方法开始执行。
方法的要求:
1. 一般以test开头(软性规定)
2. public修饰,没有返回值, 没有参数(硬性规定)
运行方式:
1. 选中方法,然后右键run
2. 选中类,然后右键run。 会运行该类所有的单元测试方法。
*/
public class Demo01JUnit {
public void testMethod() {
System.out.println("testMethod");
}
public void testFunction() {
System.out.println("testFunction");
}
}
02. 单元测试的其他注解
/*
单元测试中的其他注解:
@Before: 使用Before修饰的方法, 会在每次单元测试方法执行之前执行。
@After: 使用After修饰的方法, 会在每次单元测试方法执行之后执行。
@BeforeClass: 使用BeforeClass修饰的方法, 会在所有单元测试方法执行之前执行。终身只执行一次。
@AfterClass: 使用AfterClass修饰的方法, 会在所有单元测试方法执行之后执行。终身只执行一次。
被BeforeClass以及AfterClass修饰的方法必须使用static修饰。
*/
public class Demo02JUnit {
public static void afterClassMethod() {
System.out.println("afterClassMethod...");
}
public static void beforeClassMethod() {
System.out.println("beforeClassMethod...");
}
public void beforeMethod() {
System.out.println("beforeMethod...");
}
public void afterMethod() {
System.out.println("afterMethod...");
}
public void testMethod() {
System.out.println("testMethod...");
}
public void testFunction() {
System.out.println("testFunction...");
}
}
03. 反射的介绍
参考 Java基础学习完结:【Junit、反射、注解】的图文章源自JAVA秀-https://www.javaxiu.com/741.html
04. 获取Class对象的三种方式
public class Person {
private String name;
private int age;
public String hobby;//爱好
public void sleep(String address, int time) {
System.out.println("在" + address + "睡觉, 睡了" + time + "秒");
}
public void eat() {
System.out.println("吃饭");
}
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Person() {
}
private Person(String name) {
this.name = name;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
/*
获取一个类的Class对象的三种方式:
1. 通过对象调用getClass方法获取。
Class getClass():可以通过对象获取类的Class
2. 通过类的class属性获取。 每一个数据类型都有一个隐藏的属性叫做class, 可以获取对应的Class对象
类名.class
3. 通过Class的静态方法forName获取
static Class forName(String className): 参数要传递一个全类名(包含包的类名), 并获取该类的Class对象。
一个类只有一个Class类型的对象,无论怎么获取,获取的都是同一个Class
*/
public class Demo01GetClass {
public static void main(String[] args) throws ClassNotFoundException {
//1. 通过对象调用getClass方法获取。
Person p = new Person();
Class clazz = p.getClass();//获取到的Class对象里面保存的是Person类的信息,是用来描述Person类的。
System.out.println(clazz);
//2. 通过类的class属性获取。
Class clazz2 = Person.class;
System.out.println(clazz2);
//3. 通过Class的静态方法forName获取
Class clazz3 = Class.forName("cn.itcast.demo02_reflect.Person");
System.out.println(clazz3);
System.out.println(clazz == clazz2);
}
}
05. Class中的常见方法
/*
Class中的常见的方法:
String getName(): 获取类的名字(含有包的类名)
String getSimpleName(): 获取简单的类名(不含包的类名)
(重要)T newInstance():直接创建该类的对象(使用的空参构造创建对象)
*/
public class Demo02ClassMethod {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
//获取Person类的Class对象
//该Class对象保存了Person类的信息。
Class clazz = Class.forName("cn.itcast.demo02_reflect.Person");
//String getName(): 获取类的名字(含有包的类名)
System.out.println(clazz.getName()); //cn.itcast.demo02_reflect.Person
//String getSimpleName(): 获取简单的类名(不含包的类名)
System.out.println(clazz.getSimpleName());//Person
System.out.println("===========================");
//(重要)T newInstance():直接创建该类的对象(使用的空参构造创建对象)
Object obj = clazz.newInstance(); //因为clazz是Person的Class对象,所以使用newInstance方法创建的是Person对象。
//System.out.println(obj);
Person p = (Person) obj;
System.out.println(p.getName() + "-" + p.getAge());
}
}
06. 反射获取空参构造方法并使用
/*
反射获取构造方法
在Class中,有一个方法叫做getConstructor,可以获取一个类中的构造方法
Constructor[] getConstructors(): 获取类的中的所有的构造方法。
Constructor getConstructor(Class... parameterTypes): 获取一个类中指定的构造方法。 参数为构造方法的参数列表。
上面两个方法只能获取public权限的方法,其他权限的无法获取。
Constructor表示构造方法, 里面的功能有:
T newInstance(Object... initargs): 使用该构造方法创建对象, 参数为调用构造方法时传递的实际参数。
*/
public class Demo03ReflectConstructor {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
method2();
}
/*
Constructor getConstructor(Class... parameterTypes): 获取一个类中指定的构造方法。
获取Person类中的空参数的构造方法, 然后根据这个空参数的构造方法创建对象。
*/
public static void method2() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取Person类的Class对象
Class clazz = Class.forName("cn.itcast.demo02_reflect.Person");
//获取类中的空参数构造方法
//Constructor getConstructor(Class... parameterTypes): 获取一个类中指定的构造方法。 参数是要获取的构造方法的参数列表
Constructor c = clazz.getConstructor();//如果getConstructor不写任何参数,表示的是获取空参数的构造方法。
//使用空参构造方法创建对象
Object obj = c.newInstance();//因为获取的是空参数构造方法,所以不需要传递参数, 所以newInstance省略参数。
System.out.println(obj);
}
/*
Constructor[] getConstructors(): 获取类的中的所有的构造方法。
*/
public static void method() throws ClassNotFoundException {
//获取Person类的Class对象
Class clazz = Class.forName("cn.itcast.demo02_reflect.Person");
//Constructor[] getConstructors(): 获取类的中的所有的构造方法。
Constructor[] cs = clazz.getConstructors();
//遍历数组,打印里面的每一个内容
for(Constructor c : cs) {
System.out.println(c);
}
}
}
07. 反射获取有参构造方法并使用
/*
Class中获取Constructor的方法
Constructor[] getConstructors(): 获取类的中的所有的构造方法。
Constructor getConstructor(Class... parameterTypes): 获取一个类中指定的构造方法。 参数为构造方法的参数列表。
上面两个方法只能获取public权限的方法,其他权限的无法获取。
Constructor表示构造方法, 里面的功能有:
T newInstance(Object... initargs): 使用该构造方法创建对象, 参数为调用构造方法时传递的实际参数。
注意: 所有的数据类型都有class属性,包括基本类型。
反射主要就三个步骤:
1. 获取类的Class对象。
2. 通过Class对象获取类的内容(构造方法,成员方法, 成员变量)
3. 使用这个内容。
*/
public class Demo04ReflectConstructor {
//通过反射获取有参构造,并根据有参构造创建对象。
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取类的Class对象
Class clazz = Class.forName("cn.itcast.demo02_reflect.Person");
//获取有参构造
//public Person(String name, int age)
Constructor c = clazz.getConstructor(String.class, int.class);//表示要获取的构造方法第一个参数是String,第二个参数是int。
//T newInstance(Object... initargs): 使用该构造方法创建对象。参数表示调用构造方法时传递的实际参数。
Object obj = c.newInstance("老王", 20);//因为c表示的是两个参数的构造方法,所以使用该构造方法创建对象时,必须要传递两个实际参数。
System.out.println(obj);
}
}
08. 暴力反射构造方法
/*
暴力反射(不推荐,因为会破坏封装性)
暴力反射构造方法,可以使用Class中的以下方法获取Constructor:
Constructor[] getDeclaredConstructors():获取所有的构造方法(任何权限,包括私有)
Constructor getDeclaredConstructor(Class... parameterTypes): 获取指定给的构造方法(任何权限,包括私有)
私有的成员虽然可以通过暴力反射的方法获取到,但是不能直接使用, 因为在Java中有一个安全检查机制,私有的内容是不能再外边直接使用的。
解决方式: 取消这个安全检查机制。
Constructor表示构造方法
Method 表示成员方法
Field 表示成员变量。
上面这些类有一个公共的父类AccessibleObject, 这个父类中有一个方法可以取消安全检查机制。
void setAccessible(boolean flag): 如果参数是true表示取消权限检查。
*/
public class Demo05ReflectConstructor {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
method2();
}
/*
Constructor getDeclaredConstructor(Class... parameterTypes)获取指定给的构造方法(任何权限,包括私有)
获取Person中的private修饰的构造方法,并且使用该构造方法创建对象
构造方法:private Person(String name)
*/
public static void method2() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取类的Class对象
Class clazz = Class.forName("cn.itcast.demo02_reflect.Person");
//获取指定的私有的构造方法
//private Person(String name)
Constructor c = clazz.getDeclaredConstructor(String.class);
//在使用私有的构造方法之前,取消安全检查机制
c.setAccessible(true);
//通过获取到的构造方法创建对象
Object obj = c.newInstance("诸葛亮");
System.out.println(obj);
}
/*
Constructor[] getDeclaredConstructors():获取所有的构造方法(任何权限,包括私有)
*/
public static void method() throws ClassNotFoundException {
//获取类的Class对象
Class clazz = Class.forName("cn.itcast.demo02_reflect.Person");
//调用getDeclaredConstructors获取所有的构造方法
Constructor[] cs = clazz.getDeclaredConstructors();
//遍历数组
for (Constructor c : cs) {
System.out.println(c);
}
}
}
09. 反射获取空参成员方法并执行
/*
反射获取成员方法。
Class中有一些方法,可以获取到一个类中的成员方法:
Method[] getMethods(): 获取到类中所有的成员方法。
Method getMethod(String name, Class... parameterTypes):获取到的类中的指定的成员方法。 第一个参数是方法名, 第二个参数是该方法的参数列表。
上面两个方法只能获取到一个类中public权限的成员方法。
Method表示的是成员方法,Method有一些功能:
Object invoke(Object obj, Object... args): 让该方法执行。
参数obj: 表示调用者对象。 如果调用的是静态方法,该参数传递null。
参数args: 表示调用方法时传递的实际参数。
返回值Object表示方法调用后的结果。
*/
public class Demo06ReflectMethod {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
method2();
}
/*
Method getMethod(String name, Class... parameterTypes):获取到的类中的指定的成员方法。 第一个参数是方法名, 第二个参数是该方法的参数列表。
获取Person中的eat()方法, 并让eat方法执行
*/
public static void method2() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
//获取类的Class对象
Class clazz = Class.forName("cn.itcast.demo02_reflect.Person");
//获取Person中的eat方法
Method m = clazz.getMethod("eat");//第一个参数eat表示要获取的方法名是eat,第二个参数可变参数没有传递任何内容,表示获取的是空参数的eat方法
//调用invoke,让方法执行
//创建一个Person对象,用来执行方法
Object obj = clazz.newInstance();
//Object invoke(Object obj, Object... args): 让该方法执行。
//m表示的是eat方法,所以是eat方法执行, 因为第一个参数是obj,所以表示通过obj调用了eat方法,
//第二个参数应该是可变参数, 但是没有写任何东西,表示没有传递任何实际参数
m.invoke(obj); //相当于 obj.eat();
}
/*
Method[] getMethods(): 获取到类中所有的成员方法。
*/
public static void method() throws ClassNotFoundException {
//获取类的Class对象
Class clazz = Class.forName("cn.itcast.demo02_reflect.Person");
//通过类的Class对象调用getMethods获取所有的成员方法
Method[] methods = clazz.getMethods();
//遍历打印数组
for (Method method : methods) {
System.out.println(method);
}
}
}
10. 反射获取成员方法
/*
反射获取有参成员方法并执行
Class中有一些方法,可以获取到一个类中的成员方法:
Method[] getMethods(): 获取到类中所有的成员方法。
Method getMethod(String name, Class... parameterTypes):获取到的类中的指定的成员方法。 第一个参数是方法名, 第二个参数是该方法的参数列表。
上面两个方法只能获取到一个类中public权限的成员方法。
Method表示的是成员方法,Method有一些功能:
Object invoke(Object obj, Object... args): 让该方法执行。
参数obj: 表示调用者对象。 如果调用的是静态方法,该参数传递null。
参数args: 表示调用方法时传递的实际参数。
返回值Object表示方法调用后的结果。
*/
public class Demo07ReflectMethod {
//获取有参成员方法并执行
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
//获取类的Class
Class clazz = Class.forName("cn.itcast.demo02_reflect.Person");
//获取Person中的sleep方法
//public void sleep(String address, int time)
Method method = clazz.getMethod("sleep", String.class, int.class);
//调用这个sleep方法,让它执行
//创建一个Person对象
Object obj = clazz.newInstance();
//通过invoke方法让sleep执行
method.invoke(obj, "天上人间", 3);// 相当于obj.sleep("天上人间", 3);
}
}
11. 反射获取set方法以及get方法完成赋值以及取值
/*
反射获取set/get方法分别完成赋值和取值的操作。
setName/getName
*/
public class Demo08ReflectMethod {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
//获取Person的Class
Class clazz = Class.forName("cn.itcast.demo02_reflect.Person");
//通过Class创建Person对象
Object obj = clazz.newInstance();
//获取setName方法给对象属性赋值
//clazz调用getMethod获取方法
Method setMethod = clazz.getMethod("setName", String.class);//获取setName方法,setName有一个字符串的参数
//执行setName
setMethod.invoke(obj, "王叔叔");//相当于obj.setName("王叔叔");
//获取getName方法,然后通过getName方法获取姓名的值。
Method getMethod = clazz.getMethod("getName");
Object result = getMethod.invoke(obj); //obj.getName();
System.out.println(result);
}
}
12. 反射操作成员变量
/*
反射获取成员变量(了解)
在Class中有一些方法可以获取到成员变量
Field[] getFields():获取到类中所有的成员变量。
Field getField(String name) :获取类中的指定的成员变量,参数是成员变量的名字。
上面两个方法只能获取到public权限的成员变量。
Field表示成员变量,里面也有一些功能:
void set(Object obj, Object value):给成员变量设置值。
参数obj:表示给哪个对象的成员变量设置值。
参数value:表示设置成什么值。
Object get(Object obj): 获取该成员变量的值。
参数obj: 表示获取哪个对象的成员变量的值。
返回值Object: 表示获取到的结果。
*/
public class Demo09ReflectFiled {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException {
method2();
}
/*
获取Person中的hobby成员变量,赋值。
*/
public static void method2() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
//获取Person的Class
Class clazz = Class.forName("cn.itcast.demo02_reflect.Person");
//获取hobby成员变量
Field field = clazz.getField("hobby");
//给hobby属性赋值
//创建Person对象
Object obj = clazz.newInstance();
//给Person对象的hobby属性赋值
field.set(obj, "编程");//相当于obj.hobby="编程"
//获取obj的hobby属性值
System.out.println(field.get(obj));//相当于输出流 obj.hobby
}
/*
获取Person中的所有的成员变量
*/
public static void method() throws ClassNotFoundException {
//获取Person的Class
Class clazz = Class.forName("cn.itcast.demo02_reflect.Person");
//通过class对象获取所有的成员变量
Field[] fields = clazz.getFields();
for (Field field : fields) {
System.out.println(field);
}
}
}
/*
注解: @XXX
1. 注解是从JDK5之后才开始有的。
2. 注解可以加在类上面, 方法上, 成员变量上, 方法参数上....
3. 注解是用来完成功能的,每一个注解都可以完成一些功能。
注解和注释的区别:
注释:注释是给程序员看的, 注释不会影响到程序的编译和执行。
注解:注解是给程序看的, 会影响到程序的运行, 程序会根据注解完成一些功能。
常见的注解:
@Override: 用来检查方法是否是重写父类的方法。
@FunctionalInterface: 检查接口是否是函数式接口。
@Deprecated:标注方法已经过时,不推荐使用。
*/
public class Demo01Anno {
public static void main(String[] args) {
method();
}
public static void method() {
System.out.println("非常好用的方法");
}
}
15. 注解的定义以及使用
/*
自定义注解的格式:
public @interface 注解名 {
}
*/
public class Demo02Anno {
name = "王叔叔", age = 18, hobbies = "洗脚")
( public void method() {
}
}
/*
在注解中,可以定义一些属性
属性格式:
数据类型 属性名();
数据类型 属性名() default 默认值;
注解中的属性的数据类型只能是下面这几种
1. 八种基本数据类型(byte short int long float double boolean char)
2. Class, String, 枚举, 注解
3. 以上所有类型的一维数组。
注解可以加在类上面, 方法上, 成员变量上, 方法参数上....
使用格式为@注解名
给注解属性赋值的格式
@注解名(属性名=属性值, 属性名=属性值)
注意:
1. 如果注解中的属性没有默认值,那么在使用的时候必须要进行赋值
2. 如果注解中的属性有默认值,那么在使用的时候可以赋值也可以不赋值, 如果不赋值该属性的值就是默认值。
3. 如果注解中的属性是一个数组, 那么在赋值的使用可以使用大括号包裹多个内容。
4. 如果注解中的属性是一个数组, 在赋值的时候只需要赋值一个元素,那么可以省略大括号。
*/
public @interface Student {
//姓名
String name();
//年龄属性,默认值为0
int age() default 0;
//爱好属性
String[] hobbies();
}
16. 注解中的特殊属性value
/*
特殊属性value
如果一个注解中只有一个没有默认值的属性(可以有多个属性,但是没有默认值必须是1个), 并且这个属性叫做value,那么在给该属性赋值的使用,可以省略属性名。否则必须写全。
*/
public @interface Book {
String value();
int price() default 10;
}
"西游记")
(public class Demo03Anno {
"红楼梦")
( int num;
"三国演义")
( public void method() {
}
}
17. Target元注解的使用
/*
元注解:
1. 元注解也是注解。
2. 元注解是用来修饰注解的注解。
3. 元注解要加在注解上面, 可以对某些注解进行一些限制。
常见的元注解:
1.@Target
2.@Retention
*/
public class Demo01Anno {
public void method() {
}
}
/*
@Target是一个元注解,用来修饰注解。
@Target用来限制注解的使用位置, 如果不使用@Target进行限制,那么注解可以在任何位置使用。
Target中有一个属性叫做value, 这个属性用来表示被修饰的注解可以使用在哪些位置。
value是ElementType数组类型, 里面可以传递多个数据。
ElementType是一个枚举,枚举就是一个特殊的类, 枚举中的每一个属性都是本身类型, 枚举中的属性可以通过枚举名直接调用。
ElementType中的每一个属性都有特别的含义:
ElementType.TYPE: 用在类,接口上
ElementType.FIELD:用在成员变量上
ElementType.METHOD: 用在方法上
ElementType.PARAMETER:用在参数上
ElementType.CONSTRUCTOR:用在构造方法上
ElementType.LOCAL_VARIABLE:用在局部变量上
我们要向Target的value属性位置传递ElementType中的属性,不同的属性有不同的含义。
*/
//@Target(ElementType.TYPE)//被修饰的注解只能使用在类的上面。
//@Target(ElementType.METHOD) //被修饰的注解只能用在方法上
ElementType.TYPE, ElementType.METHOD})
({public @interface MyAnno {
}
18. Retention元注解的使用
public class Demo02Anno {
}
/*
@Retention 元注解, 用来修饰注解。
@Retention用来限制注解的生命周期, 如果使用@Retention修饰, 注解默认只在源代码阶段以及.class文件中有效,运行时期内存中是没有的。
Retention只有一个属性叫做value, 这个属性是RetentionPolicy类型。 该属性表示的是被修饰的注解的生命周期。
RetentionPolicy是一个枚举类型, 里面的每一个属性都有特别的含义。 我们要向Retention的value属性位置传递RetentionPolicy的属性。
RetentionPolicy每个属性的含义:
RetentionPolicy.SOURCE: 被修饰的注解只在源代码阶段有效, 一旦编译,到了.class中就会消失。
RetentionPolicy.CLASS: 被修饰的注解只在源代码以及编译后的.class中有效
RetentionPolicy.RUNTIME: 被修饰的注解在源代码阶段,编译后的.class中,运行时内存中有效。
*/
RetentionPolicy.SOURCE)//表示被修饰的注解只在源代码阶段有效
(public @interface MyAnno1 {
}
RetentionPolicy.CLASS)//被修饰的注解在源代码以及class中有效
(public @interface MyAnno2 {
}
RetentionPolicy.RUNTIME)//被修饰的注解在源代码,class,运行时内存中都有效。
(public @interface MyAnno3 {
}
19. 注解的解析
/*
注解的解析: 注解解析就是获取注解中的内容(比如属性),并进行处理。
解析相关的API:
Annotation:接口, 所有注解都默认实现了这个接口。
AnnotatedElement: 接口, 里面定义了很多方法可以操作注解
Annotation[] getAnnotations():获取所有的注解
T getAnnotation(Class annotationClass):获取指定的注解, 方法参数传递的是哪个注解的Class,那么获取的就是哪个注解。
boolean isAnnotationPresent(Class annotationClass): 判断指定注解是否存在。 参数为注解的Class。
解析注解需要结合反射技术去使用, 我们之前学习的Class,Method,Constructor,File反射有关的都实现了AnnotatedElement接口
如果要操作类上面的注解,那么我们就使用Class调用AnnotatedElement中的方法操作注解就可以了
如果要操作方法上面的注解,那么我们就使用Method调用AnnotatedElement中的方法操作注解就可以了
如果要操作成员变量上面的注解,那么我们就使用Field调用AnnotatedElement中的方法操作注解就可以了
*/
//获取BookStore这个类上面的Book注解中的属性,并进行输出。
public class Demo01AnnoParse {
public static void main(String[] args) throws ClassNotFoundException {
//因为要获取BookStore类上面的注解,所以要先获取BookStore的Class对象
Class clazz = Class.forName("cn.itcast.demo05_anno_parse.BookStore");
//调用isAnnotationPresent判断这个类上面有么有注解。
boolean flag = clazz.isAnnotationPresent(Book.class);//判断有没有Book注解
//判断,如果有注解,那么就获取该注解
if(flag) {
//获取BookStore这个类上面Book注解
Annotation a = clazz.getAnnotation(Book.class);
//向下转型
Book book = (Book)a;
//获取book中的属性并输出
System.out.println(book.value());
System.out.println(book.price());
System.out.println(book.author());
}
}
}
value = "Java从入门到精通", author = "佚名")
(public class BookStore {
}
RetentionPolicy.RUNTIME) //修改该注解的生命周期,让这个注解在运行时期内存中也有效。
(public @interface Book {
//value表示书名
String value();
//price表示价格
int price() default 100;
//author 作者
String author();
}
20. 模拟单元测试
/*
练习: 定义@MyTest注解, 模拟单元测试。
定义@MyTest注解,在多个方法上面加上这个@MyTest注解,然后运行带有@MyTest注解的方法。
步骤:
获取MyTestDemo的所有的方法,遍历这些方法,判断遍历到的方法上有没有@Test注解,如果有,就让该方法执行。
*/
public class Demo01Test {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException {
//获取MyTestDemo的Class对象
Class clazz = Class.forName("cn.itcast.demo06_anno_test.MyTestDemo");
//创建对象,以后调用方法使用。
Object obj = clazz.newInstance();
//clazz调用getMethods,获取到所有的方法(public权限)
Method[] methods = clazz.getMethods();
//遍历这些方法
for (Method method : methods) {
//判断遍历到的方法上有没有MyTest注解
if(method.isAnnotationPresent(MyTest.class)) {
//如果方法上有这个注解,那么就让这个方法执行。
method.invoke(obj);
}
}
}
}
RetentionPolicy.RUNTIME) //使用元注解修饰, 让该注解在运行时期内存中也有效。
(ElementType.METHOD)//限制该注解只能用在方法上。
(public @interface MyTest {
}
public class MyTestDemo {
public void methodA() {
System.out.println("methodA....");
}
public void methodB() {
System.out.println("methodB....");
}
public void methodC() {
System.out.println("methodC....");
}
public void methodD() {
System.out.println("methodD....");
}
public void methodE() {
System.out.println("methodE....");
}
}
文章源自JAVA秀-https://www.javaxiu.com/741.html继续阅读
速蛙云 - 极致体验,强烈推荐!!!购买套餐就免费送各大视频网站会员!快速稳定、独家福利社、流媒体稳定解锁!速度快,全球上网、视频、游戏加速、独立IP均支持!基础套餐性价比很高!这里不多说,我一直正在使用,推荐购买:https://www.javaxiu.com/59919.html

资源分享QQ群
本站是JAVA秀团队的技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
评论