zoukankan      html  css  js  c++  java
  • java 反射

    1.定义:

    • 在运行状态中对于任意一个类都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

    2.应用场景:

    • 编码阶段不知道需要实例化的类名是哪个,需要在runtime从配置文件中加载
    • 在runtime阶段,需要临时访问类的某个私有属性

    3.定义People和子类Men

    • public class People {
          private int age;
          private String name;
          public int hight;
      
          public People() {
          }
      
          public People(int age, String name) {
              this.age = age;
              this.name = name;
          }
      
          public People(String name) {
              this.name = name;
          }
      
      
          public void eat(String food) {
              System.out.println("人吃饭");
          }
      
      
          private String sleep() {
              System.out.println("人睡觉");
              return "2";
          }
      
          public String grow() {
              return "成长";
          }
      }
      public class Men extends People {
          public int age;
          private String name;
          private Men(){}
          public Men(int age,String name){
              this.age=age;
              this.name=name;
          }
      
      
          public void eat(String food){
              System.out.println("男人吃饭");
          }
      
      
          private String sleep(){
              System.out.println("男人睡觉");
              return "2";
          }
      }

    4.获取类对象的三种方式

            Class clazz = Men.class;//根据类名获得class
            Class clazz1 = Class.forName("reflect.Men");//根据类路径获得class
            Men men = new Men(12, "男");
            Class clazz2 = men.getClass();//通过对象获得
            System.out.println(clazz == clazz1);//相等
            System.out.println(clazz == clazz2);//相等        

    5.获得构造函数

     //获取构造器
            Constructor[] constructors = clazz.getConstructors();//获取全部构造器(公有)(包括父类)
            Constructor[] constructors1 = clazz.getDeclaredConstructors();//获取全部构造器(无论类型)(不包括父类)
            Constructor constructor = clazz.getConstructor(int.class, String.class);//获取给定参数的构造器(公有)(包括父类)
            Constructor constructor1 = clazz.getDeclaredConstructor(int.class, String.class);//获取给定参数的(无论类型)(不包括父类)
    
            System.out.println("参数类型为(int,String)的公有构造器:
    " + constructor);
            System.out.println("参数类型为(int,String)的构造器(无论类型):
    " + constructor1);
            System.out.println("全部公有构造器:");
            for (Constructor c : constructors
                    ) {
                System.out.println(c);
            }
            System.out.println("全部构造器(无论类型):");
            for (Constructor c : constructors1
                    ) {
                System.out.println(c);
            }
            //用构造器创建对象
            Men o = (Men) constructor.newInstance(1, "男");
            System.out.println("构造器创建的对象:
    " + o);
    • 执行结果

    参数类型为(int,String)的公有构造器:
    public reflect.Men(int,java.lang.String)
    参数类型为(int,String)的构造器(无论类型):
    public reflect.Men(int,java.lang.String)
    全部公有构造器:
    public reflect.Men(int,java.lang.String)
    全部构造器(无论类型):
    private reflect.Men()
    public reflect.Men(int,java.lang.String)
    构造器创建的对象:
    reflect.Men@27c170f0

    6.获得对象的参数

    System.out.println("参数名为age的公有字段:
    " + clazz.getField("age"));//得到公有字段(包括父类)
            System.out.println("参数名为age的字段(无论类型):
    " + clazz.getDeclaredField("age"));//得到所有类型字段(不包括父类)
            Field[] fields = clazz.getFields();
            System.out.println("所有公有的字段");
            for (Field f : fields
                    ) {
                System.out.println(f);//得到所有公有的字段(包括父类)
            }
    
            Field[] fields1 = clazz.getDeclaredFields();
            System.out.println("所有字段(无论类型)");
            for (Field f : fields1
                    ) {
                System.out.println(f);//得到所有字段无论类型(不包括父类)
            }
            Field f1 = clazz.getField("age");
            f1.set(men, 12);//给对象属性赋值
    • 执行结果

    参数名为age的公有字段:
    public int reflect.Men.age
    参数名为age的字段(无论类型):
    public int reflect.Men.age
    所有公有的字段
    public int reflect.Men.age
    public int reflect.People.hight
    所有字段(无论类型)
    public int reflect.Men.age
    private java.lang.String reflect.Men.name

    7.获得方法

     Method method = clazz.getMethod("eat",String.class);//获取方法名为eat参数类型为String的公有方法(包括父类)
            Method method1 = clazz.getDeclaredMethod("eat",String.class);//获取方法名为eat参数类型为String的方法(无论类型)(不包括父类)
            Method[] methods = clazz.getMethods();//获取全部公有方法(包括父类)
            Method[] methods1 = clazz1.getDeclaredMethods();//获取全部方法(无论类型)(不包括父类)
    
            System.out.println("方法名为eat,参数类型为String的公有方法:
    "+method);
            System.out.println("方法名为eat,参数类型为String的方法(无论类型):
    "+method);
            System.out.println("全部公有方法:");
            for (Method m:methods
                    ) {
                System.out.println(m);
            }
            System.out.println("全部方法(无论类型):");
            for (Method m1:methods1
                    ) {
                System.out.println(m1);
            }
            //调用方法
            method.invoke(men,"苹果");
    • 执行结果

    方法名为eat,参数类型为String的公有方法:
    public void reflect.Men.eat(java.lang.String)
    方法名为eat,参数类型为String的方法(无论类型):
    public void reflect.Men.eat(java.lang.String)
    全部公有方法:
    public void reflect.Men.eat(java.lang.String)
    public java.lang.String reflect.People.grow()
    public final void java.lang.Object.wait() throws java.lang.InterruptedException
    public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
    public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
    public boolean java.lang.Object.equals(java.lang.Object)
    public java.lang.String java.lang.Object.toString()
    public native int java.lang.Object.hashCode()
    public final native java.lang.Class java.lang.Object.getClass()
    public final native void java.lang.Object.notify()
    public final native void java.lang.Object.notifyAll()
    全部方法(无论类型):
    private java.lang.String reflect.Men.sleep()
    public void reflect.Men.eat(java.lang.String)
    男人吃饭

     

     

     

    ***********注意点***************

    带有Declared内容的方法是获取不包含父类的所有访问限制内容,不带Declared的是获取包含父类的public的内容

  • 相关阅读:
    scrapy爬虫框架学习
    python:面向对象—— __slots__来限制实例的属性命名范围
    列表list 的常用操作
    python replace()用法
    python 字符串 空字符串 len()
    python 字符串 编码问题
    python中语句、函数、类、模块、包之间的关系
    matplotlib 绘制正玄余玄曲线
    Es6/CommonJs/AMD模块系统的差异以及用法
    BOM和DOM的区别
  • 原文地址:https://www.cnblogs.com/ll9507/p/11296836.html
Copyright © 2011-2022 走看看