【Java高级语法】(二十二)运行时环境访问支持类:API知识总结分享,深入解析Runtime运行时环境访问支持类~

news2024/9/27 9:24:17

Java高级语法详解之运行时环境访问支持类

  • 1️⃣ 概念
  • 2️⃣ 优势和缺点
  • 3️⃣ 使用
    • 3.1 Runtime 类常用方法
    • 3.2 使用技巧
  • 4️⃣ 应用场景
  • 5️⃣ 业务场景实战
    • 5.1 场景一:执行外部脚本
    • 5.2 场景二:动态加载类
  • 🌾 总结

在这里插入图片描述

1️⃣ 概念

Java Runtime 类是 Java 标准库中的关键类之一。它提供了对当前Java虚拟机(JVM)实例的访问和控制,允许程序动态地修改和管理运行时环境。

Java Runtime 是Java虚拟机(JVM)的一个实例,代表了正在执行Java应用程序的运行时环境。Runtime 类封装了访问底层系统和控制JVM行为的方法,使得程序能够与运行时环境进行交互。

2️⃣ 优势和缺点

优点

  • 控制整个JVMRuntime 类提供了许多方法来管理JVM的行为,如内存管理、垃圾回收等。这使得开发人员可以根据自己的需求调整JVM的配置,并最大限度地使用系统资源;
  • 外部交互能力:通过 exec 方法,Runtime 类可以执行外部命令,允许程序与操作系统进行交互。这样,Java程序就能够调用其他系统工具或执行外部脚本;
  • 动态类加载Runtime 类支持在运行时动态加载和卸载类,从而提供了更大的灵活性和扩展性。

缺点

  • 安全性问题:某些 Runtime 类的方法可能存在安全风险,尤其是在处理用户输入时。开发人员应谨慎使用这些方法,并进行适当的输入验证和安全性检查;
  • 平台依赖性Runtime 类涉及底层系统资源和行为,因此其表现可能依赖于特定的操作系统和JVM实现。在不同平台上的行为可能会有所差异。

3️⃣ 使用

3.1 Runtime 类常用方法

下表列出了 Java Runtime 类的全部操作方法API,并简要描述了每个方法的作用。开发人员可以根据自己的需求选择适当的方法来管理和控制Java运行时环境:

方法说明
Runtime getRuntime()返回与当前 Java 应用程序相关的运行时对象
Process exec(String command) 在单独的进程中执行指定的字符串命令。该方法返回一个代表进程的Process对象,可以通过该对象获取进程的输入流、输出流和出错流,并与进程进行交互
gc()运行垃圾回收器。调用该方法可以尽力触发垃圾回收器的执行,以回收不再使用的对象占据的内存空间
addShutdownHook(Thread hook)注册在JVM关闭时执行的钩子程序。当Java虚拟机即将关闭时,会先执行注册的所有钩子程序,然后终止虚拟机
boolean removeShutdownHook(Thread hook)注销先前通过addShutdownHook方法注册的钩子。该方法返回一个布尔值,表示注销是否成功。注意,只能在钩子尚未运行并且没有被虚拟机触发关闭序列的情况下才能成功注销钩子。否则,调用将不起作用,并返回false
load(String filename)加载关联的本地库。根据给定的文件名加载与当前平台兼容的动态链接库或共享对象文件
loadLibrary(String libname)加载具有指定名称的本地库。加载与系统属性java.library.path中定义的路径和给定的库名相对应的本地库。通常,库名由平台相关的前缀和后缀组成,如libexample.so (UNIX)和 example.dll(Windows)
long freeMemory()返回Java虚拟机中的可用内存量(以字节为单位)。这个值会随着程序运行而不断变化,可以用来监视内存的使用情况
long maxMemory()返回Java虚拟机试图使用的最大内存量(以字节为单位)。这个值通常取决于底层操作系统和Java虚拟机的限制
long totalMemory()返回Java虚拟机中的堆的当前大小(以字节为单位)。堆是用于存储Java对象和数组的区域,这个值通常是JVM启动时分配的初始堆大小,但在程序运行时也会动态增长
runFinalization()强制终止正在等待的所有用户定义的对象的finalize()方法。当垃圾回收器确定某个对象需要被回收时,会先执行其finalize()方法。但是,在执行回收之前,可以通过runFinalization()强制执行处于等待状态的所有finalize()方法
int availableProcessors()返回可用的处理器数目。这个值表示当前系统上可用的处理器核心数量,用于评估处理能力和并行性
traceInstructions(boolean on)启用或禁用指令跟踪。当参数ontrue,JVM将输出正在执行的每条指令。这个方法主要用于调试目的,可能影响程序性能和日志文件大小
traceMethodCalls(boolean on)启用或禁用方法调用跟踪。当参数ontrue,JVM将输出方法调用的信息,包括方法入口和出口。这个方法主要用于调试目的,可能影响程序性能和日志文件大小
exit(int status)终止当前正在运行的Java虚拟机。参数status表示退出状态码,通常非零值表示异常终止
halt(int status)强制终止当前虚拟机,非标准化暴力关机。这个方法直接终止虚拟机,不会正常释放资源。参数status表示终止状态码,通常非零值表示异常终止
InputStream getLocalizedInputStream(InputStream in)获取本地化标准输入流。这个方法返回一个用于读取控制台输入的输入流。根据操作系统的不同,可能会返回不同的输入流
OutputStream getLocalizedOutputStream(OutputStream out)获取本地化标准输出流。这个方法返回一个用于向控制台输出数据的输出流。根据操作系统的不同,可能会返回不同的输出流

下面是一个使用 Runtime 类的案例程序,逐行解释了每个方法的使用和功能:

import java.io.IOException;

public class RuntimeExample {
    public static void main(String[] args) throws IOException {

        // getRuntime - 返回与当前 Java 应用程序相关的运行时对象
        Runtime runtime = Runtime.getRuntime();

        // exec - 在单独的进程中执行指定的字符串命令
        Process process = runtime.exec("echo Hello World");

        // gc - 运行垃圾回收器
        runtime.gc();

        // load - 加载关联的本地库
        runtime.load("/path/to/library.so");

        // loadLibrary - 加载具有指定名称的本地库
        runtime.loadLibrary("mylibrary");

        // freeMemory - 返回Java虚拟机中的可用的内存量
        long freeMemory = runtime.freeMemory();
        System.out.println("Free memory: " + freeMemory + " bytes");

        // maxMemory - 返回Java虚拟机试图使用的最大内存量
        long maxMemory = runtime.maxMemory();
        System.out.println("Max memory: " + maxMemory + " bytes");

        // totalMemory - 返回Java虚拟机中的堆的当前大小
        long totalMemory = runtime.totalMemory();
        System.out.println("Total memory: " + totalMemory + " bytes");

        // runFinalization - 强制终止正在等待的所有的用户定义的对象的finalize方法
        runtime.runFinalization();

        // traceInstructions - 启用/禁用指令跟踪
        runtime.traceInstructions(true);

        // traceMethodCalls - 启用/禁用方法调用跟踪
        runtime.traceMethodCalls(true);

        // availableProcessors - 返回可用的处理器数目
        int numProcessors = runtime.availableProcessors();
        System.out.println("Available processors: " + numProcessors);

        // addShutdownHook - 注册在JVM关闭时执行的钩子程序
        Thread thread = new Thread() {
            public void run() {
                System.out.println("Shutting down JVM...");
            }
        };
        runtime.addShutdownHook(thread);

        // exit - 终止当前正在运行的Java虚拟机
        runtime.exit(0);

        // removeShutdownHook - 注销先前通过addShutdownHook方法注册的钩子
        runtime.removeShutdownHook(thread);

        // halt - 强制终止当前虚拟机,非标准化暴力关机,不会正常释放资源
        runtime.halt(1);
    }
}

通过以上示例,我们可以了解每个 Runtime 类的方法和功能。请注意,有些方法涉及到I/O操作或系统资源,需要显式处理异常或适当的关闭流。另外,本例中的部分方法可能会导致程序终止或环境变化,请谨慎使用,并根据自己的需求进行适当的调整和优化。

特别的对于 runtime.load("/path/to/library.so");runtime.loadLibrary("mylibrary");这两个方法在执行之前,先确保已经在正确对应位置创建好了本地库文件,否则调试时可能出现下列异常:

java.lang.UnsatisfiedLinkError: Expecting an absolute path of the library: /path/to/library.so 
或
java.lang.UnsatisfiedLinkError: no mylibrary in java.library.path

程序运行结果如下:

Free memory: 126201960 bytes
Max memory: 1866465280 bytes
Total memory: 126877696 bytes
Available processors: 12
Shutting down JVM...

3.2 使用技巧

  • 要注意安全性问题,特别是在处理用户输入时要做好验证和过滤;
  • 避免滥用 Runtime 类的方法,合理利用其功能并进行适当的优化以提高性能;
  • 避免频繁创建 Runtime 类的实例,可以通过 getRuntime 方法获取单例实例,以减少资源消耗;
  • 在调用 exec 执行外部命令时,注意处理输入、输出流以避免阻塞;
  • 使用 addShutdownHook 方法注册终止钩子,确保程序退出前能够释放资源。

4️⃣ 应用场景

Java Runtime 在需要与底层操作系统进行交互的情况下常被使用:

  • 执行外部命令,如运行系统命令行工具或执行脚本
  • 动态加载本机库文件,与本地代码进行交互;
  • 监听JVM关闭事件,执行清理活动或保存状态等操作。

5️⃣ 业务场景实战

5.1 场景一:执行外部脚本

下面是一个演示如何使用 Runtime 类来执行外部脚本的 Java 实例程序:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ExecuteScriptExample {
    public static void main(String[] args) {
        Runtime runtime = Runtime.getRuntime();
        try {
            // 使用 runtime.exec() 方法执行外部脚本
            Process process = runtime.exec("python script.py");

            // 获取外部脚本的输入流,并创建 BufferedReader 对象用于读取输出结果
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            
            String line;
            while ((line = reader.readLine()) != null) {
                // 处理外部脚本输出的每一行
                System.out.println(line);
            }

            // 等待外部进程结束并获取退出值
            int exitCode = process.waitFor();
            
            if (exitCode == 0) {
                // 外部脚本执行成功
                System.out.println("External script executed successfully.");
            } else {
                // 外部脚本执行失败
                System.err.println("External script execution failed. Exit code: " + exitCode);
            }
        } catch (IOException | InterruptedException e) {
            // 处理异常
            e.printStackTrace();
        }
    }
}

上面代码首先通过 Runtime.getRuntime() 方法获取运行时对象,这是一个表示当前 Java 应用程序相关的运行时环境的单例对象。然后使用 runtime.exec() 方法执行外部脚本命令,例如 "python script.py"

通过 Process.getInputStream() 方法获取外部进程的输入流,并使用 InputStreamReaderBufferedReader 对象读取脚本的输出结果。在循环中,处理并打印每一行输出。

最后,通过 process.waitFor() 方法等待外部进程结束,并获取退出值。根据约定,退出值为 0 表示成功执行,而非零值表示出现错误。根据退出值,可以确定外部脚本是成功执行还是失败。

这个实例展示了如何在 Java 中使用 Runtime 类来执行外部脚本,并处理输出结果和异常情况。注意,使用 runtime.exec() 执行外部命令需要谨慎处理,特别是针对从用户输入或不受信任的源代码中派生的命令。建议对脚本及其参数进行适当的验证和限制,以确保安全性。

5.2 场景二:动态加载类

下面是一个演示如何使用 Runtime 类结合反射机制来动态加载类的Java实例程序:

import java.lang.reflect.Method;

public class DynamicClassLoadingExample {
    public static void main(String[] args) {
        try {
            // 创建Runtime对象
            Runtime runtime = Runtime.getRuntime();

            // 加载需要动态加载的类的全限定名
            String className = "com.example.MyClass";

            // 使用ClassLoader动态加载类
            Class<?> dynamicClass = runtime.getClass().getClassLoader().loadClass(className);

            // 创建类的实例
            Object instance = dynamicClass.newInstance();

            // 调用类中的方法
            Method method = dynamicClass.getDeclaredMethod("doSomething");
            method.invoke(instance);
        } catch (ClassNotFoundException e) {
            // 处理类未找到异常
            e.printStackTrace();
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
            // 处理其他异常
            e.printStackTrace();
        }
    }
}

上面代码首先创建了一个 Runtime 对象,用于表示当前Java应用程序相关的运行时环境。

然后,通过获取 runtime 对象的类加载器(runtime.getClass().getClassLoader())和指定的类名,使用 loadClass() 方法从类加载器中动态加载需要的类。

接下来,通过反射实例化被加载的类,使用 dynamicClass.newInstance() 创建了一个类的实例,并使用反射获取被加载类中的方法(例如 doSomething()),并使用 method.invoke(instance) 调用该方法。

这个实例演示了如何使用 Runtime 类动态加载类,并调用其中的方法。需要注意,动态加载类在某些场景下是有用的,但也应谨慎使用。合理地处理异常情况以及对类名、方法等进行适当的验证和限制是非常重要的。

🌾 总结

Java Runtime 类作为Java虚拟机的实例,对于动态地控制运行时环境至关重要。通过提供各种功能和方法,例如执行外部命令、管理内存和垃圾回收,以及动态加载和卸载类,Runtime 类使得Java程序能够更加灵活地与底层系统进行交互。

然而,开发人员需要注意安全性、性能优化及平台依赖性等方面,以确保代码的可靠性和效率。熟练使用 Runtime 类,并根据具体需求进行合理的优化,将有助于实现更强大和高效的Java应用程序。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/695975.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

去面试测试开发你必须要知道的基本知识(建议收藏)

目录 1.对测试开发的理解 2.为什么做测试而不是去做开发 3.如何处理矛盾 4.职业发展 5.你认为测试人员需要具备哪些素质。&#xff08;你有哪些优点围绕这些来说&#xff09; 6.你为什么能够胜任这个岗位 7.测试方法 黑盒测试 白盒测试 8.测试的阶段 9.测试的类型 …

SpringBoot - 集成Quartz框架之常用配置

Quartz是一款Java编写的开源任务调度框架&#xff0c;同时它也是Spring默认的任务调度框架。它的作用其实类似于Java中的Timer定时器以及JUC中的ScheduledExecutorService调度线程池&#xff0c;当然Quartz作为一个独立的任务调度框架无疑在这方面表现的更为出色&#xff0c;功…

四章:FTP详细介绍+winServer2008搭建ftp服务器+winServer2008开启端口

目录 一、FTP介绍 二、FTP服务器架设 三、FTP服务器连接验证 四、winServer2008开启端口 一、FTP介绍 FTP就是文件传输协议。用于互联网双向传输&#xff0c;控制文件下载空间在服务器复制文件从本地计算机或本地上传文件复制到服务器上的空间。 我们在工作中经常使用到FTP…

golang,OpenGL,计算机图形学(三)

代码仓库 https://github.com/phprao/go-graphic 颜色 光源照射到物体上&#xff0c;一部分颜色被吸收&#xff0c;另一部分无法吸收的被反射到人眼&#xff0c;于是呈现出了颜色。 当我们把光源的颜色与物体的颜色值相乘&#xff08;而不是点乘&#xff09;&#xff0c;所…

【C语言初阶】带你轻松玩转所有常用操作符最终篇——下标引用、函数调用和结构体成员,表达式求值

君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 Hello,这里是君兮_&#xff0c;前几天非常忙没空更新&#xff0c;现在终于闲下来了&#xff0c;这是今天爆肝更新的第二篇&#xff0c;也是我们【C语言初阶】带你轻松玩转所有常用操作符的最后一篇&#xff0c;废话不多说…

nestjs post请求提交数据量太大会报错 [ExceptionsHandler] request entity too large

背景 在传给后端接口的数据&#xff0c;是一个超过1.5mb的json字符串&#xff0c;通过nest filter的时候直接被拦截掉了&#xff0c;返回【 请求体太长】的错误。 还没有到达contraller&#xff0c;就直接被框架拦截掉了&#xff0c; import { ExceptionFilter, Catch, Argu…

vue——实现表格的拖拽排序功能——技能提升

最近在写后台管理系统时&#xff0c;遇到一个需求&#xff0c;就是要实现表格的排序。 就是拖动某一行数据&#xff0c;放在指定位置&#xff0c;然后保存的时候根据最终的排序来处理生产单顺序字段。 参考大神的链接&#xff1a;vue-实现拖拽排序功能&#xff1a;https://ju…

mac苹果电脑,怎么批量修改文件名称

mac苹果电脑&#xff0c;如何批量修改文件名称&#xff1f;在苹果电脑上对文件名称进行修改是一件非常简单的操作&#xff0c;相信任何mac电脑用户都知道怎么操作&#xff0c;只需要选中要修改名称的文件&#xff0c;然后点击鼠标右键&#xff0c;然后会弹出一个菜单&#xff0…

layui代码记录

// 归档弹框jsguiDangRemarkInfo : function(activiti, buttonConf, call) {layui.use([layer, form, laydate], function () {var layer layui.layer;var form layui.form;var laydate layui.laydate;layer.open({type: 1,title: 归档备注信息,area: [350px, 300px],conten…

Redis 6.2.4集群搭建

1. 说明 这里使用的是redis的cluster集权模式&#xff0c;没有用哨兵模式&#xff08;哨兵模式依赖哨兵节点&#xff0c;哨兵节点一旦挂掉就不再高可用了&#xff0c;因此没有采用&#xff09;。 由于Redis Cluster至少需要6个节点&#xff0c;因此&#xff0c;这里咱们采用的…

【运维】Linux系统 AnolisOS [CentOs替代品]

【运维】AnolisOS 安装 CentOs替代品 下载 - OpenAnolis 龙蜥操作系统开源社区 Index of /anolis/ (aliyun.com)

(编辑器)HBuilderX怎么自动格式化代码

(编辑器)HBuilderX怎么自动格式化代码 解决参考&#xff1a;https://blog.csdn.net/G806218/article/details/127833356

CSDN 个性化推荐的数据治理

目录 1. 背景2. 数据治理2.1 从内容层面提升数据质量2.2 从用户层面提升数据质量2.3 增加特定数据的曝光2.4 保证数据的正确性与实效性 3. 总结 相关阅读 CSDN 个性化推荐系统的设计和演进如何支持研发对CSDN个性化推荐系统重构 1. 背景 CSDN 的个性化推荐流在主站中是一个很…

用UDP套接字实现客户端和服务端通信

IP地址和port端口号 IP地址 数据有IP(公网)标识一台唯一的主机。 port端口号 为了更好的标识一台主机上服务进程的唯一性&#xff0c;我们采用端口号port&#xff0c;标识服务器进程&#xff0c;客户端进程的唯一性&#xff01; ip端口号 IP地址(主机全网唯一性) 该主机上的端…

一年省七位数,得物自建HFDS在 Flink Checkpoint 场景下的应用实践

1 背景 随着Flink实例的迁移下云以及新增需求接入&#xff0c;自建Flink平台规模逐渐壮大&#xff0c;当前总计已超4万核运行在自建的K8S集群中&#xff0c;然而 Flink 任务数的增加&#xff0c;特别是大状态任务&#xff0c;每次Checkpoint 时会产生脉冲式带宽占用&#xff0…

统计项目代码行数工具cloc

Ubuntu用户 使用cloc在ubuntu内统计代码行数 安装cloc工具 sudo apt-get install cloc进入需要统计的目录内&#xff0c;然后执行 cloc .然后就会显示文件目录中的文件数(files)、空白行数(blank)、注释行数(comment)和代码行数(code)。 Windows 用户 也是使用cloc工具 …

leecode-下一排列

题目 题目 分析 妈呀&#xff0c;其实我直接调用函数&#xff0c;一行代码就通过了hhh&#xff0c;不过这种取巧的方式不可取&#xff0c;还是得老老实实的写。 首先需要明白什么叫下一排列&#xff1f; 比如输入&#xff1a; 1 5 8 4 7 6 5 3 1 答案就是&#xff1a; 1 5 …

什么是楼宇卫生间智慧厕所系统

楼宇卫生间智慧厕所系统是专为写字楼、办公楼、商场、集团大厦、工厂等应用场景所设计的解决方案。它利用全自动采集和监控智能化、无线数据传输功能&#xff0c;通过云平台管理软件和手机端应用&#xff0c;实现了公厕的智能化管理和使用者的便利。 随着城市化进程的加速&…

[Json]控制返回数据是否包含某个属性

控制返回数据是否包含某个属性 在我们返回给前端的Json格式的数据时&#xff0c;通常我们会定义一个类&#xff0c;里面定义几个成员变量用来定义返回给前端的具体内容&#xff0c;例如&#xff1a; package cn.tedu.csmall.commons.web;import io.swagger.annotations.ApiMo…

HDLbits--Exams/2013 q2bfsm

try1: module top_module (input clk,input resetn, // active-low synchronous resetinput x,input y,output f,output g ); parameter a0,b1,x12,x23,y14,y25,g16,g07;//b为resetn无效后的状态&#xff0c;在b状态使f保持一个周期 //b收到1后转移到x1&#xff0c;x1收到…