反射与注解

反射:

     反射是一种在程序运行过程中,根据类的名称或者已有对象来获取类的属性,方法,父类等有关信息,以及对象实例的创建和实例类型的判断的一种机制。 

     反射中常用的类Class,Class类其实表示的是正在运行的Java应用程序中的类和接口。其中Class的forName()方法可以获得Class对象的实例,再通过newInstance()方法即可获得该类的一个新实例。

1.获取一个类Class对象的三种方法:  Class类的forName()方法;类的class属性;对象的getClass()方法。以及基本数据类型及其包装类的Class对象;数据类型相同并维度相同时,其对象共享一个Class对象。具体见如下实例:

class.forName();

对象.getClass():

类.class;


public class Test1 {
public static void main(String[] args) throws ClassNotFoundException {
//1.采用目标类的.class属性-->每个类都有包装类(Type属性):
Class c1 = Users.class;
System.out.println(c1);

//2.Object类的getClass()方法:
Users users = new Users();
Class c2 = users.getClass();
//getSimpleClass():只获得类的名称,不包含包名
System.out.println(users);
System.out.println(c2);

//3.Class类的forName()方法:
Class c3 = Class.forName("TestMyself.Users");
System.out.println(c2);

//4.基本数据类型的Class对象,与其包装类的Class对象是Type属性获得
Class i1 = int.class;
Class i2 = Integer.TYPE;
System.out.println(i1==i2);
}
}

 

2.通过Class对象获得类的:名称;属性;方法;构造方法;

主要方法:

class.getName():获得类名;

class。getDeclaredField():获得属性;

class。getDeclaredConstructor():获得无参构造方法;

class.getDeclaredMethod():获得方法;

 1 //通过反射获得类的信息(通过Class对象):
 2 //名称;属性;方法;构造;
 3 public class Test5 {
 4     public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
 5         Class c1 = Class.forName("TestMyself.Users"); //获得Class对象
 6         Class c2 = Class.forName("java.lang.String");
 7 
 8         //1.获得类名:
 9         String name = c1.getName();
10         String simpleName = c1.getSimpleName();
11         System.out.println("name:"+name+"   simpleName:"+simpleName);
12         System.out.println("=================================================");
13 
14         //2.获得属性:
15         Field[] fields = c1.getFields();   //getFields():只能获得public属性
16         for (Field field : fields) {
17             System.out.println(field);
18         }
19         Field[] declaredFields = c1.getDeclaredFields(); //获得全部的属性
20         for (Field declaredField : declaredFields) {
21             System.out.println(declaredField);
22         }
23         System.out.println("============================================================");
24         
25         //3.获得方法:
26         Method[] methods = c1.getMethods(); //getMethods():获得本类和父类的所有public方法
27         for (Method method : methods) {
28             System.out.println("public 方法:"+method);
29         }
30 
31         Method[] Methods = c1.getDeclaredMethods();//获得本类的所有方法
32         for (Method declaredMethod : Methods) {
33             System.out.println("本类方法:"+declaredMethod);
34         }
35         //对于要获得重载方法:如果只知道方法名字是找不到具体方法的
36         //("方法名",参数的Class对象)
37         System.out.println("==================================================");
38         Method getAge = c1.getMethod("getAge", null);
39         Method setName = c1.getMethod("setName", String.class);
40         System.out.println(getAge);
41         System.out.println(setName);
42 
43         //4.获得构造器:
44         //获得无参构造
45         System.out.println("=====================================================");
46         Constructor constructor = c1.getConstructor();
47 
48         //获得有参构造:(参数的Class对象)
49         Constructor constructor1 = c1.getConstructor(String.class, int.class, int.class);
50 
51         System.out.println("无参构造:"+constructor);
52         System.out.println("有参构造:"+constructor1);
53 
54 
55     }
56 }

3.通过Class对象来创建对象,并调用执行方法;获得属性并设置属性:

用到的主要方法:

newInstance():使用无参构造创建对象;

getDeclaredConstructor(形参的Class对象。。。)获得有参构造器->construcctor.newInstance(实参。。。):来创建对象;

getDeclaredMethod(“方法名”,形参Class对象。。。):获得一个方法-->method.invoke(对象,实参。。。):执行这个方法;

getDeclaredFiled("属性名"):获得属性;field.setAccessible(true):设置权限来访问私有属性,field.set(对象,实参);

 1 public class Test06 {
 2     public static void main(String[] args) throws
 3             ClassNotFoundException,
 4             IllegalAccessException,
 5             InstantiationException,
 6             NoSuchMethodException,
 7             InvocationTargetException,
 8             NoSuchFieldException {
 9         //1.使用Class对象来获得构造方法,并创建对象
10         Class<?> c = Class.forName("TestMyself.Users");   //创建Class对象
11 
12         //用无参构造创建对象  c.newInstance()
13         Users u1 = (Users) c.newInstance();
14         System.out.println(u1);               //重写toString()方法
15 
16         //用有参构造创建对象: constructor.newInstance("张三","001","18")
17         Constructor<Users> declaredConstructor = (Constructor<Users>) c.getDeclaredConstructor(String.class, int.class, int.class);
18         Users u2 = declaredConstructor.newInstance("张三", 001, 18);
19         System.out.println(u2);
20 
21         //2.通过反射来调用普通方法:
22         Users u3 = (Users) c.newInstance();  //使用无参构造创建一个对象
23         Method getAge = c.getDeclaredMethod("getAge");       //获得方法("方法名",Class对象。。。)
24         Method setAge = c.getDeclaredMethod("setAge", int.class);
25         setAge.invoke(u3,19);
26         getAge.invoke(u3);    //invoke(对象,实参)来执行方法
27         System.out.println(u3.getAge());
28 
29         //3.通过反射来获得(私有)属性,并给属性赋值
30         Users u4 = (Users) c.newInstance();  //创建一个对象
31         Field field = c.getDeclaredField("name");
32         field.setAccessible(true);    //设置权限,从而可以访问private属性
33         field.set(u4,"王五");
34         System.out.println(u4.getName());
35 }
36 }

 注解:

1.常见的三种注解: 

 

 2 @SuppressWarnings("all")  //取消警告的注解
 3 
 4 public class Test1 extends Thread {
 5 
 6 
 7     @Override  //@Override:方法重写的注解
 8     public void run() {
 9         System.out.println("@Override");
10     }
11 
12     public static void main(String[] args) {
13 
14 
15         Test();
16         new Test1().start();
17 
18 
19     }
20 
21     @Deprecated  //方法过时的注解
22     public static void Test(){
23         System.out.println("@Deprecated");
24 
25     }
26 }

2.自定义注解:

 1 //自定义
 2 public class Test2{
 3 
 4     public static void main(String[] args) {
 5         Test();
 6     }
 7 
 8 
 9     @Myannotation@Deprecated //可以多个在一起定义
10     public static void Test(){
11         System.out.println("啦啦啦");
12     }
13     @Myannotation2(name="张三",age={1,2})
14     public static void Test3(){
15         System.out.println("this is zhang san!");
16     }
17 }
18 
19 
20 @Target(ElementType.METHOD)     //参数是唯一的value,可以省略不写
21     @Retention(RetentionPolicy.RUNTIME)
22 @Documented
23 @interface Myannotation{
24 //    String value();
25 //    char[] name();
26 
27     String value() default "张三";
28     String [] schools() default {"李四","王五","赵6"};
29 
30 }
31 
32 
33 
34 @Target(value={ElementType.METHOD,ElementType.FIELD})   //注解作用范围
35 @Retention(value=RetentionPolicy.RUNTIME)           //注解的作用时刻
36 
37 @interface Myannotation2{
38     String name();  //参数
39     int[] age();
40 }

 

原文地址:https://www.cnblogs.com/xbfchder/p/10989583.html