java_反射机制

获取字节码文件的三种方式
package com.bjpowernode.java.reflect;

import java.util.Date;

/*
反射机制:
 先获取字节码文件,怎么获取java.lang.Class实例??
   三种方式:

 */
public class ReflectTest01 {
    public static void main(String[] args) {
        /*
            Class.forName();
            1.静态方法
            2.方法的参数必须是字符串
            3.字符串需要的是一个完整的类名
            4.完整的类名必须带有包名:java.lang包不能省略
         */
        Class c1=null;
        Class c2=null;
        try {
            c1=Class.forName("java.lang.String"); // c1代表的是String.class文件,或者说c1代表的是String类型
            c2=Class.forName("java.util.Date"); // c2代表的是Date类型
            Class c3=Class.forName("java.lang.Integer");// c3代表的是Integer类型
            Class c4=Class.forName("java.lang.System"); // c4代表的是System类型
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        // java种任何一个对象都有一个方法:getClass()
        String s="abc";
        Class x=s.getClass(); // x代表String类型
        System.out.println(c1==x);// true 说明c1和x的内存地址一样,说明他们代表的都是String类型

        Date date=new Date();
        Class y=date.getClass();
        System.out.println(y==c2); // true c2和y两个变量保存的内存地址都是一样的

        // java语言中任何一种类型,包括基本数据类型,它都有class属性
        Class z=String.class; // 代表String类型
        Class k=Date.class;
        Class f=int.class;
        Class e=double.class;
        System.out.println(x==z);
    }
}

读属性文件的方式

package com.bjpowernode.java.bean;

import java.io.InputStream;
import java.util.Properties;

/*
读属性文件
 */
public class IoPropertiesTest {
    public static void main(String[] args) throws Exception{
        // 直接以流的形式返回
        InputStream reader=Thread.currentThread().getContextClassLoader().getResourceAsStream("classinfo2.properties");
        Properties pro=new Properties();
        pro.load(reader);
        reader.close();
        // 通过key获取value
        String className=pro.getProperty("className");
        System.out.println(className);

    }
}

资源绑定器(掌握这种就好啦)
package com.bjpowernode.java.reflect;

import java.util.ResourceBundle;

/*
资源绑定器
java.util包下的资源绑定器,便于获取属性配置文件
使用属性配置文件的时候,属性配置文件必须放在类路径下
 */
public class ResourceBundleTest {
    public static void main(String[] args) {
        // 资源绑定器,只能绑定xxx.properties 并且这个文件必须在类路径下,问价扩展名必须为properties
        // 并且后面的扩展名不用写
        ResourceBundle bundle=ResourceBundle.getBundle("classinfo2");
        String className=bundle.getString("className");
        System.out.println(className);

    }
}

类加载器(底层东西 了解)
  • 关于JDK中自带的类加载器:
    1. 什么是类加载器??
  • 专门负责加载类的命令/工具
  • classLoader
    1. JDK中自带了三个类加载器
  • 启动类加载器
  • 扩展类加载器
  • 应用类加载器
    1. 假设有这样一段代码:
  • String s=“abc”
  • 代码在开始执行前,会将所需要的类全部加载到JVM当中,通过类加载器加载,看到以上代码会找String.class文件,找到就进行加载,那么是怎么加载的??
  • 首先通过“启动类加载器”去加载文件
  • 如果“启动类加载器”没有加载到,那么就会去执行“扩展类加载器”
  • 如果“扩展类加载器”没有加载到,最后会去“应用类加载器”中去加载

这个机制叫做:双亲委派机制

反射一个类中的属性(了解)
package com.bjpowernode.java.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/*
反射Student类当中所有的Field
 */
public class ReflectTest05 {
    public static void main(String[] args) throws Exception{
        // 获取整个类
        Class studentClass =Class.forName("com.bjpowernode.java.bean.Student");
        System.out.println(studentClass); // 这是一个完整类名

        String simpleName=studentClass.getSimpleName();
        System.out.println(simpleName);// 这是一个简单类名


        // 获取类中所有的public 修饰的Field
        Field[] fields=studentClass.getFields();
        System.out.println(fields.length);
        // 取出这个Field
        Field f=fields[0];
        // 取出这个Field的名字
        String fieldName=f.getName();
        System.out.println(fieldName);

        System.out.println("--------------------------------");
        // 获取所有的field
        Field[] fs=studentClass.getDeclaredFields();
        System.out.println(fs.length);
        for (Field field:fs){
            // 获取属性的修饰符列表
            int i=field.getModifiers(); // 返回的是一个int 类型  每一个数字是一个代号
            System.out.println(i);
            // 可以将这个数字转换为字符串吗??
            String modifierString=Modifier.toString(i);
            System.out.println(modifierString);


            // 获取属性的类型
            Class fieldType=field.getType();
            String fName=fieldType.getSimpleName();
            System.out.println(fName);
            // 获取属性的名字
            System.out.println(field.getName());
        }


    }
}

直接进行反编译(了解)
package com.bjpowernode.java.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/*
反编译:反编译一个类的属性Filed
 */
public class ReflectTest06 {
    public static void main(String[] args) throws Exception{
        // 创建这个是为了拼接字符串
        StringBuilder s=new StringBuilder();

        Class studentClass=Class.forName("java.lang.Thread");

        s.append( Modifier.toString(studentClass.getModifiers()) +" class "+studentClass.getSimpleName()+"{\n");

        Field[] fields=studentClass.getDeclaredFields();
        for (Field field:fields){
            s.append("\t");
            s.append(Modifier.toString(field.getModifiers()));
            s.append(" ");
            s.append(field.getType().getSimpleName());
            s.append(" ");
            s.append(field.getName());
            s.append(";\n");
        }
        s.append("}");
        System.out.println(s);
    }
}

通过反射机制反射一个类的属性(重点******)
package com.bjpowernode.java.reflect;

import java.lang.reflect.Field;

/*
 必须掌握:
   怎么通过反射机制访问一个java对象的属性??
     给属性赋值  set
     获取属性的值 get
 */
public class ReflectTest07 {
    public static void main(String[] args) throws Exception{
        // 使用反射机制去获取一个类的属性
        Class studentClass=Class.forName("com.bjpowernode.java.bean.Student"); // 通过反射机制拿到class
        Object obj=studentClass.newInstance(); // obj就是当前类

        // 获取no属性(属性和属性之间依靠名字来区分)
        Field noField=studentClass.getDeclaredField("no");

        // 给obj对象的no属性赋值
        // 还是需要三要素:
        // 一:obj对象
        // 二:no属性
        // 三:赋值
        noField.set(obj,1111); // 给obj对象的no赋值1111

        // 读取属性的值
        System.out.println(noField.get(obj));

        // 可以访问私有属性的值吗??
        Field nameField=studentClass.getDeclaredField("name");
        // 打破封装   缺点:反射机制的特点  可能会给不法分子留下机会
        nameField.setAccessible(true);
        // 给name赋值
        nameField.set(obj,"jack");
        // 获取属性值
        System.out.println(nameField.get(obj));

    }
}

可变长度
package com.bjpowernode.java.reflect;
/*
可变长度参数
     int.. args 这就是可变参数
     语法是:类型...(注意:一定是3个点)

      可变长度参数要求的参数个数是:0到N个
      可变长度参数在参数列表中只能有一个,并且要放在最后一个

      可变长度可以看作一个数组

 */
public class ArgsTest {
    public static void main(String[] args) {
        m();
        m(10);
        m(10,20);

        m3("ab","ac","aa","ss");

        //直接传一个数组
        m3(new String[]{"我","是","中","国","人"});
    }
    public static void m(int... args){
        System.out.println("m方法执行了");
    }

    public static void m2(int a,String... args){}

    public static void m3(String... args){
        // args有length属性,说明args是一个数组
        // 可以将可变长度当作一个数组来看
        for (int i=0;i<args.length;i++){
            System.out.println(args[i]);
        }
    }
}



反编译方法
package com.bjpowernode.java.reflect;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/*
反射Method
 */
public class ReflectTest08 {
    public static void main(String[] args) throws Exception{
        // 还是得先拿到class
        Class userServiceClass=Class.forName("com.bjpowernode.java.service.UserService");
        // 获取所有得Method
        Method[] methods= userServiceClass.getDeclaredMethods();
        System.out.println(methods.length);
        // 遍历方法
        for (Method method:methods){
            // 获取修饰符列表
            System.out.println(Modifier.toString(method.getModifiers()));
            // 获取方法的返回值类型
            System.out.println(method.getReturnType().getSimpleName());
            // 获取方法名
            System.out.println(method.getName());
            // 获取方法的修饰符列表
            Class[] parameterTypes= method.getParameterTypes();
            for (Class parameterType:parameterTypes){
                System.out.println(parameterType.getSimpleName());
            }
        }
    }
}





package com.bjpowernode.java.service;
/*
用户业务类
 */
public class UserService {
    // 登录方法
    public boolean login(String name,String password){
        if ("admin".equals(name) && "123".equals(password))
            return true;
        return false;
    }

    // 退出系统方法
    public void logout(){
        System.out.println("退出系统成功");
    }
}

通过反射机制去调用方法(重点********)
package com.bjpowernode.java.reflect;

import java.lang.reflect.Method;

/*
通过反射机制怎么去调方法(重点)

反射机制让代码很具有通用性
 */
public class ReflectTest10 {
    public static void main(String[] args) throws Exception{
        // 获取一个类
        Class userServiceClass =Class.forName("com.bjpowernode.java.service.UserService");
        // 获取当前的类的对象
        Object obj=userServiceClass.newInstance();
        // 获取方法名
        Method loginMethod=userServiceClass.getDeclaredMethod("login", String.class, String.class);
        // 调用方法 几个要素
        // 对象  方法名  实参列表 返回值
        // 反射机制中最最最重要的一个方法,必须死记硬背
        Object reValue=loginMethod.invoke(obj,"admin","123");
        System.out.println(reValue);
    }
}

反编译一个类的Constructor构造方法
package com.bjpowernode.java.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;

/*
反编译一个类Constructor的构造方法
 */
public class ReflectTest11 {
    public static void main(String[] args) throws Exception{
        // 进行字符串的拼接
        StringBuilder s=new StringBuilder();
        Class vipClass=Class.forName("com.bjpowernode.java.bean.Vip");
        s.append(Modifier.toString(vipClass.getModifiers()));
        s.append("class");
        s.append(vipClass.getSimpleName());
        s.append("\n");
        // 拼接构造方法
        Constructor[] constructors=vipClass.getDeclaredConstructors();
        for (Constructor constructor:constructors){
            s.append("\t");
            s.append(Modifier.toString(constructor.getModifiers()));
            s.append(" ");
            s.append(vipClass.getSimpleName());
            s.append("(");
            // 拼接参数
            Class[] parameterTypes=constructor.getParameterTypes();
            for (Class parameterType:parameterTypes){
                s.append(parameterType.getSimpleName());
                s.append(",");

            }
            s.deleteCharAt(s.length()-1);
            s.append("){}\n");
            s.append("{}\n");
        }



        s.append("}");
        System.out.println(s);
    }
}

通过反射机制怎么创建对象
package com.bjpowernode.java.reflect;

import java.lang.reflect.Constructor;

/*
通过反射机制怎么new对象

通过反射机制调用构造方法实例化java对象(这个不是重点)
 */
public class ReflectTest12 {
    public static void main(String[] args) throws Exception{
        // 使用反射机制怎么创建对象
        Class c=Class.forName("com.bjpowernode.java.bean.Vip");
        // 获取当前对象
        Object obj=c.newInstance();
        System.out.println(obj);
        // 调用有参的构造方法
        Constructor con=c.getDeclaredConstructor(int.class,String.class,String.class,boolean.class);

        // 调用构造方法new 对象
        Object newObj=con.newInstance(110,"jackson","1990-10-11",true);
        System.out.println(newObj);

        // 调用无参构造方法
        Constructor constructor=c.getDeclaredConstructor();
        Object obj2=constructor.newInstance();
        System.out.println(obj2);



    }
}

给你一个类,怎么获取这个类的父类,以及实现了那些接口??(重点**)
package com.bjpowernode.java.reflect;
/*
给你一个类,怎么去获取一个类的父类以及接口??
 */
public class ReflectTest13 {
    public static void main(String[] args) throws Exception{
        // String 举例
        Class stringClass=Class.forName("java.lang.String");
        // 获取String的父类
        Class superclass=stringClass.getSuperclass();
        System.out.println(superclass.getName());

        // 获取String 实现的所有接口
        Class[] interfaces=stringClass.getInterfaces();
        // 遍历
        for (Class inface:interfaces){
            System.out.println(inface.getName());
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值