• 反射与注解


    反射:

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

         反射中常用的类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 }

     

  • 相关阅读:
    【自用】【做题日记6】CTFHUB-文件上传
    【自用】【做题日记5】CTFHUB-XSS
    【自用】【做题日记4】CTFHUB-SQL注入
    【自用】【做题日记3】CTFHUB-密码口令
    【自用】【做题日记2】CTFHUB-信息泄露
    【自用】【做题日记1】CTFHUB-web前置技能
    前端-常用正则表达式
    ClashX 配置代理白名单
    http 网址 URL 特殊字符转义编码
    axios的post和request请求方法
  • 原文地址:https://www.cnblogs.com/xbfchder/p/10989583.html
Copyright © 2020-2023  润新知