欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java如何基于反射机制获取不同的类

程序员文章站 2022-09-12 13:54:35
什么是反射机制java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和...

什么是反射机制

java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为java语言的反射机制。反射被视为动态语言的关键(在运行阶段可以改变其结构)

特点:

1、极大的提高了程序的灵活性和扩展性,降低模块的耦合性,提高自身的适应能力

2、通过反射机制可以让程序创建和控制任何类的对象,无需提前硬编码目标类

3、能够在运行时构造一个类的对象、判断一个类所具有的成员变量和方法、调用一个对象的方法(包括 private),可能会有安全隐患

4、是构建框架技术的基础所在,使用反射可以避免将代码写死在框架中

5、包含动态类型,而 jvm 不能对动态代码优化,所以效率会比较低

在java中可以通过reflection apis在运行时动态生成class实体,通过constructor创建类实例、field访问成员属性、method调用方法

class类

在java中,每个 class 都有一个相应的 class 对象。在编译完成后,在生成的.class文件中,会产生一个class对象,用于表示这个类的类型信息。

特点:

1、由系统创建class类

2、同一个类的实例指向同一个class对象

3、通过class可以完整的得到一个类所有被加载的结构

4、class类是java反射的基础

获得class类的方法:

public class myreflect {
  public static void main(string[] args) throws classnotfoundexception {
    teacher t = new teacher();
    // 1、通过对象获得
    class c1 = t.getclass();
    // 2、forname + 全限定名 获得
    class c2 = class.forname("reflect.teacher");
    // 3、通过类名获得
    class c3 = teacher.class;
    // 4、基本数据类型的type属性获得
    class c4 = double.type;
    // 5、通过子类的class对象获得
    class c5 = c1.getsuperclass();
  }
}
class person {
  string name;
  public person() {
  }
}
class teacher extends person {
  public teacher() {
  }
}

Java如何基于反射机制获取不同的类

getxxx为获取 public 构造器、属性、方法

getdeclaredxxx 获取任意构造器、属性、方法(包括private)

setaccessible方法避开权限检测,用以访问权限不足的成员

以下不在赘述

准备:person类以及tercher子类

package reflect;

class person {
  public string name;
  private int 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;
  }

  public person() {
  }

  public person(string name, int age) {
    this.name = name;
    this.age = age;
  }

  @override
  public string tostring() {
    return "person{" +
        "name='" + name + '\'' +
        ", age=" + age +
        '}';
  }

  public string greet(string name) {
    return "hello " + name + ".";
  }
}

class teacher extends person {

}

constructor类

java.lang.reflect.constructor类是java.lang.reflect.executable类的直接子类,用于表示类的构造方法。通过class对象的 getconstructors() 方法可以获得当前运行时类的构造方法

public class myconstructor {
  public static void main(string[] args) throws exception {
    class<person> c = (class<person>) class.forname("reflect.person");

//    object person2 = c.newinstance();  //@deprecated
//    system.out.println(person2);
    constructor<person> constructor = c.getconstructor();
    person person = constructor.newinstance();
    system.out.println(person);

    // 获取 public 有参构造方法
    constructor<person> constructor1 = c.getconstructor(string.class, int.class);
    person person1 = constructor1.newinstance("jl", 18);
    system.out.println(person1);

    // 获取构造方法
    constructor<person> constructor2 = c.getdeclaredconstructor(string.class, int.class);
    constructor2.setaccessible(true);
    person person2 = constructor1.newinstance("jl", 18);
    system.out.println(person2.name);
  }
}

field类

java.lang.reflect.field类用于封装成员变量信息,调用class对象的 getfield() 或 getfields()等方法可以获得当前运行时类的成员变量

public class myfield {
  public static void main(string[] args) throws exception {
    class<?> c = class.forname("reflect.person");
    // 在person类中,无参的构造方法不能省略
    object p = c.getconstructor().newinstance();

    // 获取 public 成员变量
    field[] fields = c.getfields();
    // 获取所有成员变量(包括 private)
    field[] allfields = c.getdeclaredfields();
    //获取指定名称public变量
    field f1 = c.getfield("name");
    // 成员变量set、get
    f1.set(p, "jl");
    system.out.println(f1.get(p));

    field f2 = c.getdeclaredfield("age");  // private int age
    // 忽略权限检查,使得 private 成员可以被访问
    f2.setaccessible(true);
    f2.set(p, 18);
    system.out.println(f2.get(p));
  }
}

method类

java.lang.reflect.method类是java.lang.reflect.executable类的直接子类,用于封装成员方法的信息,调用class对象的 getmethod() 方法或 getmethods() 方法可以获得当前运行时类的指定方法或所有方法

 public class mymethod {
   public static void main(string[] args) throws exception {
     class<person> c = (class<person>) class.forname("reflect.person");
     person p = c.getconstructor().newinstance();
     // 获取所有 public 方法
     method[] methods = c.getmethods();
     // 获取 greet 方法
     method method1 = c.getmethod("greet", string.class);
     //执行 greet 方法
     system.out.println(method1.invoke(p, "jl"));
   }
 }
0

ps:主要简单说明反射的使用,关于类加载机制,性能分析等没有说明

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。