JAVA反射机制--学习笔记

基本概念

通过java中的反射机制可以操作字节码文件。class文件。
(有点类似于黑客,可以读和修改字节码文件。)

相关类介绍

相关类在java.lang.reflect.* 包下。

常用类

java.lang.Class               代表整个字节码。代表一个类型。
java.lang.reflect.Method     代表字节码文件中的方法字节码。
java.lang.reflect.Constructor 代表字节码中的构造方法字节码。
java.lang.reflect.Field         代表字节码中的属性字节码。(代表类中的成员变量和实例变量–即堆内存中的变量/方法)

反射机制—通过 forName 创建类对象
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
// 反射机制---通过 forName 创建类对象
public class IO_StreamTest {
    public static void main(String[] args) {
        InputStream reader =Thread.currentThread().getContextClassLoader().getResourceAsStream("b.properties");    //起点是类的根路径下src下
        Properties pro=new Properties();
        try {
            pro.load(reader);
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String classname=pro.getProperty("className");
        System.out.println(classname);

        Class c= null;
        try {
            c = Class.forName(classname);           // 这个操作会导致类加载。类的静态代码块会执行。
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Object obj= null;
        try {
            obj = c.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        System.out.println(obj);
    }
}
通过反射机制+properties配置文件创建对象

这种方式创建对象将更加灵活,更改properties配置文件,对象随之改变。

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
//使用反射机制+配置文件创建对象
public class Reflect_Test {             //使用反射机制创建对象,只需改配置文件 (当前b.properties内容是 java.util.Date; 更改b.properties内容,创建的类对象也发生改变)。
    public static void main(String[] args) {


        FileReader reader= null;
        try {
//            reader = new FileReader("src/Java_bilibili/Class_Test/properties");     //idea 下可以这么写,但是不如下面的写法,因为下面的写法可以移植。

            //通用路径写法    文件必须在src路径下面
            String path=Thread.currentThread().getContextClassLoader().getResource("b.properties").getPath();    //起点是类的根路径下,也即src下。
            System.out.println(path);
            reader = new FileReader(path);     //idea 下这么写


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Properties pro=new Properties();
        try {
            pro.load(reader);
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String classname=pro.getProperty("className");

        Class c= null;
        try {
            c = Class.forName(classname);           // 这个操作会导致类加载。类的静态代码块会执行。
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Object obj= null;
        try {
            obj = c.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        System.out.println(obj);
    }
}
反射机制–访问类的属性
//反编译 Class 文件主代码
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

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

        Class stuclass=Class.forName("Java_bilibili.Reflect_Test.Filed.Stu");       //获取class文件-------这个路径是相对于src路径下的路径
        Field[] fileds=stuclass.getFields();                                        //属性,  这里只能获取public 公开属性
        System.out.println(fileds.length);                                          // 长度为2,获取到了int 和 double 两个属性
        for(Field f:fileds){
            System.out.println(f.getType().getName());
            System.out.println(f.getName());
        }
        Field[] fs2=stuclass.getDeclaredFields();                                   //获取所有属性
        System.out.println(fs2.length);
        for(Field f:fs2){
            System.out.println(Modifier.toString(f.getModifiers()));
            System.out.println(f.getType().getName());
            System.out.println(f.getName());
        }
    }
}

//Stu类
public class Stu {
    //Field 翻译为字段,其实就是属性/成员
    //
    public int no;
    private String name;
    protected int age;
    boolean sex;
    public static final double PI=3.1415926;
}

//反射机制获取Class属性
import java.lang.reflect.Field;

public class Test_2 {
    public static void main(String[] args) throws Exception{
        Class stuclass=Class.forName("Java_bilibili.Reflect_Test.Filed.Stu");     //可传入java自带的类和  src路径下的类
        Object obj=stuclass.newInstance();
        Field noField=stuclass.getDeclaredField("no");                    //访问一个属性

        noField.set(obj,2222);
        System.out.println(noField.get(obj));

        Field noField2=stuclass.getDeclaredField("name");     //访问一个私有属性
        noField2.setAccessible(true);                               //打破封装后 方能赋值    //这个也是缺点,可能会给不法分子留下机会。
        noField2.set(obj,"jark");
        
    }
}
反射机制–反编译输出类中所有方法
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
//反编译输出--类中的所有方法
public class Decompile_Method {

    public static void main(String[] args) throws ClassNotFoundException {
        StringBuilder s=new StringBuilder();
        Class x=Class.forName("java.util.HashSet");             //这个可以传入可变的配置文件
        s.append(Modifier.toString(x.getModifiers())+"class "+"{"+x.getSimpleName()+"}");
        Method[] methods=x.getDeclaredMethods();        //methods :类中的方法列表
        for(Method m:methods){
            s.append("\t");
            s.append(Modifier.toString( m.getModifiers()));
            s.append(" ");
            s.append(m.getReturnType().getSimpleName());
            s.append(" ");
            s.append(m.getName());
            s.append("(");
            Class[] parameterTypes =m.getParameterTypes();
            for(Class parameterType:parameterTypes){
                s.append(parameterType.getSimpleName());
                s.append(",");
            }
            s.deleteCharAt(s.length()-1);
            s.append("){}\n");
        }
        s.append("}");
        System.out.println(s);
    }
}
反射机制–获取父类
//反射机制--获取父类
public class Get_superClass {
    public static void main(String[] args) throws Exception{
        Class stringClass=Class.forName("java.lang.String");
        Class superClass=stringClass.getSuperclass();
        System.out.println(superClass.getName());

        Class[] interfaces=stringClass.getInterfaces();     //获取接口
        for(Class in :interfaces){
            System.out.println(in.getName());
        }


    }
}

最后,附上npy沙雕的日常。

爱你
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值