Java学习第十章(四)

视频链接:https://www.bilibili.com/video/BV1Rx411876f?p=1

视频范围P823 - P833

1.获取反射属性Field

学生类

package bean;

public class Student {
    //Field翻译为字段,其实就是属性/成员
    //5个Field,分别采用了不同的访问控制权限修饰符
    public int no;//Field对象
    private String name;//Field对象
    protected int age;
    boolean sex;
    public static final double MATH_PI = 3.1415926;
}

测试类

package Reflect;

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

public class ReflectTest05 {
    public static void main(String[] args) throws Exception{
        //获取整个类
        Class studentClass = Class.forName("bean.Student");

        //获取完整类名
        String className = studentClass.getName();
        System.out.println("完整类名:" + className);

        //获取简单类名
        String simpleName = studentClass.getSimpleName();
        System.out.println("简类名:" + simpleName);

        //获取类中所有的public修饰的Field
        Field[] fields = studentClass.getFields();
        System.out.println(fields.length);//测试数组中只有2个元素
        //取出这个Field
        Field f = fields[0];
        //取出这个Field的名字
        String fieldName = f.getName();
        System.out.println(fieldName);//输出为:no

        //获取所有的Field
        Field[] fs = studentClass.getDeclaredFields();
        System.out.println(fs.length);//输出为:5

        System.out.println("------------------------");
        for (Field field : fs){
            //获取属性的修饰符列表
            int i = field.getModifiers();//返回的修饰符是一个数字,每个数字是修饰符的代号!
            System.out.println(i);
            //可以将这个”代号“数字转换成”字符串“
            String modifierString = Modifier.toString(i);
            System.out.println(modifierString);
            
            System.out.println("- - - - - ");
            
            //获取属性的类型
            Class fieldType = field.getType();
            //String fName = fieldType.getName();
            //获取简单名字
            String fName = fieldType.getSimpleName();
            System.out.println(fName);
            
            System.out.println("- - - - - ");
            
            //获取属性的名字
            System.out.println(field.getName());
            
            System.out.println("+++++++++++++++++++++++++++");
        }
    }
}

运行结果

在这里插入图片描述

2.反编译Field

通过反射机制,反编译一个类的属性Field

package Reflect;

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

public class ReflectTest06 {
    public static void main(String[] args) throws Exception{
        //创建这个是为了拼接字符串
        StringBuilder s = new StringBuilder();

        Class studentClass = Class.forName("bean.Student");

        //s.append("public class Student {");
        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);
    }
}

运行结果

在这里插入图片描述

3.通过反射机制访问对象属性【重要!!!】

给属性赋值set
获取属性的值get
反射机制让代码复杂了,但是为了一个“灵活”,这也是值得的

package Reflect;

import bean.Student;

import java.lang.reflect.Field;

public class ReflectTest07 {
    public static void main(String[] args) throws Exception{
        //不使用反射机制,去访问一个对象的属性
        Student s = new Student();
        //给属性赋值
        s.no = 1111;//三要素:给s对象的no属性赋值1111
        //读属性值
        System.out.println(s.no);//两要素:获取s对象的no属性的值

        //使用反射机制,访问一个对象的属性(set get)
        Class studentClass = Class.forName("bean.Student");
        Object obj = studentClass.newInstance();//obj就是Student对象(底层调用无参数构造方法)

        //获取no属性(根据属性的名称来获取Field)
        Field noField = studentClass.getDeclaredField("no");

        //给obj对象(Student对象)的no属性赋值
        noField.set(obj,2222);//三要素:给obj对象的no属性赋值2222

        //读取属性的值
        System.out.println(noField.get(obj));//两个要素:获取obj对象的no属性的值

        //###################################################################
        //访问私有的属性
        Field nameField = studentClass.getDeclaredField("name");

        //打破封装(反射机制的缺点:打破封装,可能会给不法分子留下机会!!!)
        //这样设置完之后,在外部也是可以访问private的
        nameField.setAccessible(true);

        //给name属性赋值
        nameField.set(obj,"jackson");
        //获取name属性的值
        System.out.println(nameField.get(obj));
    }
}

4.可变长度参数

  1. 可变长度参数:int… args
  2. 语法:类型… 【注意:一定是3个点】
  3. 可变长度参数要求的参数个数是:0~N个
  4. 可变长度参数在参数列表中必须在最后一个位置上,而且可变长度参数只能有1个
  5. 可变长度参数可以当做一个数组来看待
package Reflect;

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

        //编译报错
        //m("abc");

        m2(100);
        m2(200,"abc");
        m2(200,"abc","def");
        m2(200,"abc","def","xyz");

        m3("ab","de","kk","ff");

        String[] strs = {"a","b","c"};
        //也可以传一个数组
        m3(strs);

        //直接传一个数组
        m3(new String[]{"我","是","中","国","人"});//没必要

        m3("我","是","中","国","人");
    }

    public static void m(int... args){
        System.out.println("m方法执行了!");
    }

    //必须在最后一个位置上,而且可变长度参数只能有1个
    //public static void m2(int... args2,String... args1){};
    public static void m2(int a,String... args1){};

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

运行结果

在这里插入图片描述

5.反射Method

用户业务类

package service;

public class UserService {

    /**
     * 登录方法
     * @param name  用户名
     * @param passward 密码
     * @return true表示登录成功,false表示登录失败
     */
    public boolean login(String name,String passward){
        if ("admin".equals(name) && "123".equals(passward)){
            return true;
        }
        return false;
    }

    /**
     * 退出系统的方法
     */
    public void logout(){
        System.out.println("系统已经安全退出!");
    }

}

测试类

package Reflect;

import javax.xml.transform.Source;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class ReflectTest08 {
    public static void main(String[] args) throws Exception {
        //获取类
        Class userServiceClass = Class.forName("service.UserService");
        //获取所有的Method(包括私有的!)
        Method[] methods = userServiceClass.getDeclaredMethods();
        System.out.println(methods.length);//2

        //遍历Method
        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());
            }
        }
    }
}

运行结果

在这里插入图片描述

6.反编译Method

package Reflect;

import service.UserService;

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

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

        StringBuilder s = new StringBuilder();
        Class UserServiceClass = Class.forName("service.UserService");
        s.append(Modifier.toString(UserServiceClass.getModifiers()) + " class " + UserServiceClass.getSimpleName() +" {\n");


        Method[] methods = UserServiceClass.getDeclaredMethods();
        for (Method method: methods){
            //public boolean login(String name,String passward){}
            s.append("\t");
            s.append(Modifier.toString(method.getModifiers()));
            s.append(" ");
            s.append(method.getReturnType().getSimpleName());
            s.append(" ");
            s.append(method.getName());
            s.append("(");
            //参数列表
            Class[] parameterTypes = method.getParameterTypes();
            for (Class parameterType : parameterTypes){
                s.append(parameterType.getSimpleName());
                s.append(",");
            }
            //删除指定下标位置上的字符
            if (parameterTypes.length > 0){
                s.deleteCharAt(s.length() - 1);
            }
            s.append("){}\n");
        }
        s.append("}");
        System.out.println(s);
    }
}

运行结果
在这里插入图片描述

7.反射机制调用方法【重要!!!】

Java中区分一个方法:依靠方法名和参数列表
反射机制优点:让代码很具有通用性,可变化的内容都是写到配置文件当中,将来修改配置文件之后,创建的对象不一样了,调用的方法也不同了,但是Java代码不需要做任何改动!

package Reflect;

import service.UserService;

import java.lang.reflect.Method;

public class ReflectTest10 {
    public static void main(String[] args) throws Exception{
        //不使用反射机制
        //创建对象
        UserService userService = new UserService();
        //调用方法
        /*
        要素分析:
        1.对象:userService
        2.方法名:login
        3.实参列表:"admin","123"
        4.返回值:loginSuccess
         */
        boolean loginSuccess = userService.login("admin","123");
        System.out.println(loginSuccess?"登录成功" : "登录失败");//登录成功

        //使用反射机制调用一个对象的方法
        Class userServiceClass = Class.forName("service.UserService");
        //创建对象
        Object obj = userServiceClass.newInstance();
        //获取Method
        Method loginMethod = userServiceClass.getDeclaredMethod("login", String.class, String.class);
        //调用方法 也需要四要素
        /*
        要素分析:
        1.对象:obj
        2.方法名:loginMethod
        3.实参列表:"admin","123"
        4.返回值:retValue
         */
        //反射机制中最重要的一个方法
        Object retValue = loginMethod.invoke(obj,"admin","123");
        System.out.println(retValue);//true
    }
}

8.反射Constructor

Vip类

package bean;

public class Vip {
    int no;
    String name;
    String birth;
    boolean sex;

    public Vip() {
    }

    public Vip(int no) {
        this.no = no;
    }

    public Vip(int no, String name) {
        this.no = no;
        this.name = name;
    }

    public Vip(int no, String name, String birth) {
        this.no = no;
        this.name = name;
        this.birth = birth;
    }

    public Vip(int no, String name, String birth, boolean sex) {
        this.no = no;
        this.name = name;
        this.birth = birth;
        this.sex = sex;
    }
}

测试类

package Reflect;

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

public class ReflectTest11 {
    public static void main(String[] args) throws Exception{
        StringBuilder s = new StringBuilder();
        Class vipClass = Class.forName("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){
            //public Vip(int no, String name, String birth, boolean sex) {}
            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(",");
            }
            //删除最后下标位置上的字符
            if (parameterTypes.length > 0){
                s.deleteCharAt(s.length() - 1);
            }
            s.append("){}\n");

        }

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

运行结果

在这里插入图片描述

9.反射机制调用构造方法

Vip类

package bean;

public class Vip {
    int no;
    String name;
    String birth;
    boolean sex;

    public Vip() {
    }

    public Vip(int no) {
        this.no = no;
    }

    public Vip(int no, String name) {
        this.no = no;
        this.name = name;
    }

    public Vip(int no, String name, String birth) {
        this.no = no;
        this.name = name;
        this.birth = birth;
    }

    public Vip(int no, String name, String birth, boolean sex) {
        this.no = no;
        this.name = name;
        this.birth = birth;
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Vip{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", birth='" + birth + '\'' +
                ", sex=" + sex +
                '}';
    }
}

测试类

package Reflect;

import bean.Vip;

import java.lang.reflect.Constructor;

public class ReflectTest12 {
    public static void main(String[] args) throws Exception {
        //不使用反射机制创建对象
        Vip v1 = new Vip();
        Vip v2 = new Vip(110,"zhangsan","2022-04-06",true);

        //使用反射机制创建对象
        Class c = Class.forName("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 con2 = c.getDeclaredConstructor() ;
        Object newObj2 = con2.newInstance();
        System.out.println(newObj2);
    }
}

运行结果

在这里插入图片描述

10.获取父类和父类接口

获取一个类的父类以及实现的接口

package 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 in :interfaces){
            System.out.println(in.getName());
        }
    }
}

运行结果

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值