IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Java——反射 -> 正文阅读

[数据结构与算法]Java——反射

反射(Reflect):在运行时动态访问类与对象的技术。
Java反射技术都在java.lang.reflect包中。

现从下面的代码来看一下反射的好处:

/**
 * 四则运算接口
 */
public interface MathOperation {
    public float operate(int a, int b);
}
public class Subtraction implements MathOperation{
    @Override
    public float operate(int a, int b){
        System.out.println("执行减法运算");
        return a - b;
    }
}
/**
 * 加法
 */
public class Addition implements MathOperation{
    @Override
    public float operate(int a, int b){
        System.out.println("执行加法运算");
        return a + b;
    }
}
import java.util.Scanner;

public class ReflectSample {
    /**
     * 传统的创建对象的方式
     */
    public static void Case1(){
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入计算类目:");
        String op = scanner.next();
        System.out.print("请输入a:");
        int a = scanner.nextInt();
        System.out.print("请输入b:");
        int b = scanner.nextInt();
        MathOperation mathOperation = null;
        if (op.equals("Addition")){
            mathOperation = new Addition();
        }else if (op.equals("Subtraction")){
            mathOperation = new Subtraction();
        }else if (op.equals("Multiplication")){
            mathOperation = new Multiplication();
        } else {
            System.out.println("无效的计算类");
            return;
        }
        float result = mathOperation.operate(a,b);
        System.out.print(result);
    }

    public static void Case2(){
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入计算类目:");
        String op = scanner.next();
        System.out.print("请输入a:");
        int a = scanner.nextInt();
        System.out.print("请输入b:");
        int b = scanner.nextInt();
        MathOperation mathOperation = null;
        try {
            mathOperation =(MathOperation) Class.forName("com.company.reflect." + op).newInstance();
        } catch (Exception e){
            System.out.println("无效的计算类");
            return;
        }
        float result = mathOperation.operate(a, b);
        System.out.println(result);
    }

    public static void main(String[] args) {
        ReflectSample.Case2();
    }
}

通过上面的代码可以看出使用反射技术一行代码就可以代替上面的else if语句,而且再添加除运算等不需要再修改代码,这是应该反射是运行时创建。

反射的核心类

1.Class类
2.Constructor构造方法类
3.Method方法类
4.Field成员变量类

一、Class类的核心方法

1.Class.forName() 静态方法,用于获取指定Class对象
2.ClassObj.newInstance() 通过默认构造方法创建新的对象
3.ClassObj.getConstructor() 获取构造方法Constructor对象
4.ClassObj.getMethod() 获取方法Method对象
5.ClassObj.getField() 获取成员变量Field对象
注:ClassObj表示返回的时Object类型。
请添加图片描述
首先先建立一个实体类。

package com.company.reflect.entity;

/**
 * 员工实体类
 */
public class Employee {
    static {
        System.out.println("Employee类已被加载到jvm,并以初始化");
    }
    private Integer eno;
    public String ename;
    private Float salary;
    private String dname;

    public Employee(){
        System.out.println("Employee默认构造方法已被执行");
    }

    public Employee(Integer eno, String ename, Float salary, String dname){
        this.eno = eno;
        this.ename = ename;
        this.salary = salary;
        this.dname = dname;
        System.out.println("Employee带参构造方法已被执行");
    }

    public Integer getEno() {
        return eno;
    }

    public void setEno(Integer eno) {
        this.eno = eno;
    }

    public String getEname() {
        return ename;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public Float getSalary() {
        return salary;
    }

    public void setSalary(Float salary) {
        this.salary = salary;
    }

    public String getDname() {
        return dname;
    }

    public void setDname(String dname) {
        this.dname = dname;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "eno=" + eno +
                ", ename='" + ename + '\'' +
                ", salary=" + salary +
                ", dname='" + dname + '\'' +
                '}';
    }

    public Employee updateSalary(Float val){
        this.salary = this.salary + val;
        System.out.println(this.ename + "调薪至" + this.salary + "元");
        return this;
    }
}

下面是各个反射类的使用:

package com.company.reflect;

import com.company.reflect.entity.Employee;

public class ClassSample {
    public static void main(String[] args) {
        try {
            //Class.forName()方法将指定的类加载到JVM,并返回对应Class对象
            Class employeeClass = Class.forName("com.company.reflect.entity.Employee");
            System.out.println("Employee已被加载到JVM");
            //newInstance通过默认构造方法创建新的对象
            Employee emp =(Employee) employeeClass.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            //非法访问异常,当在作用域外访问对象方法或成员变量时抛出
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            //实例化异常,对象无法被实例化
            e.printStackTrace();
        }
    }
}

二、Constructor构造方法类的核心方法

1.ConstructorObj.newInstance() 通过对于的构造方法创建对象

package com.company.reflect;

import com.company.reflect.entity.Employee;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * 利用带参构造方法创建对象
 */
public class ConstructorSample {
    public static void main(String[] args) {
        try {
            Class employeeClass = Class.forName("com.company.reflect.entity.Employee");
            Constructor constructor = employeeClass.getConstructor(new Class[]{
                    Integer.class, String.class, Float.class, String.class
            });
            Employee employee =(Employee) constructor.newInstance(new Object[]{
               100,"李磊",1000f,"研发部"
            });
            System.out.println(employee);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            //没有找到与之对应格式的方法
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

三、Method方法类的核心方法

1.methodObj.invoke() 调用指定对象的对应方法

package com.company.reflect;

import com.company.reflect.entity.Employee;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MethodSample {
    public static void main(String[] args) {
        try {
            Class employeeClass = Class.forName("com.company.reflect.entity.Employee");
            Constructor constructor = employeeClass.getConstructor(new Class[]{
                    Integer.class, String.class, Float.class, String.class
            });
            Employee employee = (Employee) constructor.newInstance(new Object[]{
                    200, "王五" , 5000f , "营销部"
            });
            Method updateSalaryMethod = employeeClass.getMethod("updateSalary", new Class[]{
                    Float.class
            });
            Employee employee1 = (Employee)updateSalaryMethod.invoke(employee,new Object[]{1000f});
            System.out.println(employee1);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

四、Field成员变量类的主要方法

1.fieldObj.set() 为某对象成员变量赋值
2.fieldObj.get() 获取某对象指定成员变量数值

package com.company.reflect;

import com.company.reflect.entity.Employee;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

/**
 * 利用Field对成员变量赋值/取值
 */
public class FiledSample {
    public static void main(String[] args) {
        try {
            Class employeeClass = Class.forName("com.company.reflect.entity.Employee");
            Constructor constructor = employeeClass.getConstructor(new Class[]{
                    Integer.class, String.class, Float.class, String.class
            });
            Employee employee =(Employee) constructor.newInstance(new Object[]{
                    100,"玉龙",1000f,"研发部"
            });
            Field enameField = employeeClass.getField("ename");
            String ename = (String)enameField.get(employee);
            System.out.println("ename:" + ename);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
}

getDeclared系列的方法可以获取私有的方法和属性

package com.company.reflect;

import com.company.reflect.entity.Employee;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class getDeclaredSample {
    public static void main(String[] args) {
        try {
            Class employeeClass = Class.forName("com.company.reflect.entity.Employee");
            Constructor constructor = employeeClass.getConstructor(new Class[]{
                    Integer.class, String.class, Float.class, String.class
            });
            Employee employee =(Employee) constructor.newInstance(new Object[]{
                    102,"孜韦",1002f,"老鸨部"
            });
            //获取当前类所有的成员变量
            Field[] fields = employeeClass.getDeclaredFields();
            for (Field field : fields){
//                System.out.println(field.getName());
                if (field.getModifiers() == 1){ //public修饰
                    Object val = field.get(employee);
                    System.out.println(field.getName() + ":" + val);
                } else if (field.getModifiers() == 2){ //private修饰
                    String methodName = "get" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1);
                    Method getMethod = employeeClass.getMethod(methodName);
                    Object ret = getMethod.invoke(employee);
                    System.out.println(field.getName() + ":" + ret);
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-12 23:43:35  更:2021-10-12 23:46:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:46:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码