反射机制:java语言通过此可以更改字节码文件(class文件),类似黑客
与之相关的类有java.class
java.lang.reflect.Field,类的属性,静态变量,实例变量
java.lang.reflect.Constructor代表构造方法字节码,类的构造方法
java.lang.reflect.Method代表方法字节码,类的静态,非静态方法

  • 首先要获取class文件,通过class包获取,内部有一个Forname静态方法,内部参数是string类型,可以输入想要获取字节码的包
  • Class s=Class.Forname(“java.utile.date”);
  • 这里涉及到一个编译异常,用try catch解决(复习复习以前的异常处理)
  • java反射修改方法体 java反射修改静态方法_字节码

  • try catch来解决
  • java反射修改方法体 java反射修改静态方法_字节码_02

  • s==d,表达的是内存地址比较是否一样
  • 上面是一种方法,
  • 还有一种Class s=对象名.getClass();getclass()可以获取对象的class文件
  • 都保存的是.class文件。这个文件再内存中之保存一份。如下图,两个保存的都是String.class字节码文件,
package reflect01;

import com.sun.istack.internal.localization.NullLocalizable;

public class R01 {
    public static void main(String[] args) {
        Class s= null;
        try {
           s=Class.forName("java.lang.String");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        String sd="dfsd";
        Class f=sd.getClass();
        System.out.println(s==f);
    }
}

输出d的值是类的包名

java反射修改方法体 java反射修改静态方法_反射_03

输出结果为true、

下图为第三种方式

java反射修改方法体 java反射修改静态方法_构造方法_04


Class de=Date.class;

每种属性都有class字节码文件,下图int这样就不要了

java反射修改方法体 java反射修改静态方法_构造方法_05


字节码在jvm只保存一个


  • 下面介绍一个方法newinstance,通过反射来实例化对象
package reflect01;

public class R021 {
    //定义了一个R2的类以及无参构造防发
    public static void main(String[] args) {
        R02 e2=new R02();
        System.out.println(e2);
        try {
            Class x=Class.forName("reflect01.R02");
          Object object=x.newInstance();//调用类的无参构造方法,若没有无参构造方法会出错,
            // 若有其它构造方法会覆盖掉无参,也会出错
            System.out.println(object);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }
}

使用两种调用无参构造方式,第二种虽然麻烦需要try/catch,但是可拓展比直接new灵活,使用了反射机制,也保证必须无参构造方法存在

java反射修改方法体 java反射修改静态方法_字节码_06

  • 下面实践它的灵活性
    1,创建一个配置文件properties,//文本文件不用编译,用io流读的方式赋值给filereader类型文件,
    2,创建一个proper对象,该对象调用方法load加载filereader对象。proper对象就有内容了
    3,下面进行反射,Class类型接受,右方导入配置文件的名称。
    4,调用无参构造方法,只要更改配置文件里面的内容就可多类型输出各种类型的构造方法
package reflect01;

import java.io.FileReader;
import java.util.Properties;

public class R021 {
    //定义了一个R2的类以及无参构造防发
    public static void main(String[] args) throws Exception {

        FileReader fileReader = new FileReader("D:\\IDEA项目汇总斜杠分类\\heima1\\Reflect\\src\\reflect01\\classinfo.properties");
        Properties properties = new Properties();

        properties.load(fileReader);//加载存入
        fileReader.close();//关
//        Class c=Class.forName("ClassName");错误
        //加载完成要读入名字
        String classname = properties.getProperty("ClassName");//字符串类型;好啦,赋值成功
        
        Class c = Class.forName(classname);//里面可以是string,也本身只能是string
        Object object = c.newInstance();//TMD,必须加返回值啊,因为它饭会的是无参构造函数,Object 雷星来接受
        System.out.println(object);
    }
}

properties不用加分号

java反射修改方法体 java反射修改静态方法_java反射修改方法体_07


java反射修改方法体 java反射修改静态方法_构造方法_08

要注意加入路径名,不要只有类名。这是只要更改配置文件即可

java反射修改方法体 java反射修改静态方法_反射_09

  • 未完,待更新,等我做完数据库实验