java反射机制详解

反射就是在程序运行中,动态的创建对象,只要知道该类的名称,就能用它的字节码对象创建该类的对象(实例) 从而访问该类的任何方法和属性(暴力访问)

  • 什么是字节码对象?

javac 编译java文件后得到的class文件就是该类的字节码文件

javac Person.java//得到---------Person.class文件
  • 获得字节码的几种方法:

1.Object类的getclass方法------构造函数私有时无法new
2.类.class
3.class类的静态方法forname("类全路径")方法

》》》字节码对象.newinstance得到对象实例

  • 类和class对象关系

成员变量……fields
成员方法……methods
构造函数……constructor

  • 具体事例:

事例说明:

单独一个Person类  其中属性,方法,以及构造方法都是公有,私有共存

public class Person {
    private String name;
    public String password;
    String description;

    public void add(String na) {
        System.out.println("公有" + na);
    }

    private void find(String pass) {
        System.out.println("私有" + pass);
    }

    
    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }

    private Person(String name, String password, String description) {
        super();
        this.name = name;
        this.password = password;
        this.description = description;
        System.out.println("私有的构造函数:"+name+password+description);
    }

}

1.通过反射得到fields(成员属性),就是通过反射得到Person的私有属性-------一般方法没法获得

Class class1 =    Class.forName("cn.itcast.reflect.Person");//获得字节码对象

//访问私有属性-------------fields
    
    Field[] fields=class1.getDeclaredFields();//获得多个属性  返回数组
    for (Field field : fields) {
        System.out.println(field);
    }

结果:

private java.lang.String cn.itcast.reflect.Person.name
public java.lang.String cn.itcast.reflect.Person.password
java.lang.String cn.itcast.reflect.Person.description

2.通过反射访问methods(成员方法),通过反射得到Person的私有方法:

注意Person类中的find(){}方法-----私有的

private void find(String pass) {
        System.out.println("私有" + pass);
    }

暴力访问:

public static void main(String[] args) throws Exception {
  Class class1 = Class.forName("cn.itcast.reflect.Person");//获得字节码对象
  Person person=(Person) class1.newInstance();//创建对象实例 Method[] methods=class1.getDeclaredMethods(); for (Method method : methods) { System.out.println(method); } Method method=class1.getDeclaredMethod("find",String.class); method.setAccessible(true);//没有这个结果将报错 method.invoke(person, "12333"); }

结果:

public void cn.itcast.reflect.Person.add(java.lang.String)
private void cn.itcast.reflect.Person.find(java.lang.String)
私有12333


3.通过反射访问constructor(构造函数)

public static void main(String[] args) throws Exception {

Class class1 =    Class.forName("cn.itcast.reflect.Person");//获得字节码对象

Constructor[]  con=class1.getDeclaredConstructors();
    for (Constructor constructor : con) {
        System.out.println(constructor);
    }
    
    Constructor co=class1.getDeclaredConstructor(String.class,String.class,String.class);
    co.setAccessible(true);
    Person p=(Person) co.newInstance("da","xiao","da");
    System.out.println(p);
    
    
    }

结果:

private cn.itcast.reflect.Person(java.lang.String,java.lang.String,java.lang.String)
public cn.itcast.reflect.Person()
私有的构造函数:daxiaoda
cn.itcast.reflect.Person@139a55
  • 与单例设计模式

单例设计模式核心就是构造函数私有化,但是通过java反射机制可以破坏这种模式,通过反射还是可以访问私有构造函数


》》》》》装逼小福利:静态代码块中的语句没有main方法也可以编译,但是代码块末尾加system.exit(0)

Public Person{
  static {
      System.out.println("hello!!!");
      System.exit(0);    //这句是为了防止编译报错
}  
}
原文地址:https://www.cnblogs.com/wangsr-suc/p/8917346.html