java动态加载jar包,并运行其中的类和方法

本文介绍了一种在Java环境中动态加载外部JAR包的方法。通过一个具体示例,展示了如何定义接口、创建实现该接口的类并打包为JAR,最后在主程序中加载并调用JAR包中的类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

动态加载jar包,在实际开发中经常会需要用到,尤其涉及平台和业务的关系的时候,业务逻辑部分可以独立出去交给业务方管理,业务方只需要提供jar包,就能在平台上运行。

下面通过一个实例来直观演示:

第一:定义一个抽象类 AbstractAction (稍后换成接口的实例)

package com.java.loader;

public abstract class AbstractAction {
	public abstract String action();
}

第二:写个实体类继承一下 TestAction

package com.java.jarloader;

import com.java.loader.AbstractAction;

public class TestAction extends AbstractAction{
	public String action() {
		System.out.println("I am working ! ");
		return "this ActionTest class";
	}
}

第三:将TestAction所在的包导出成jar包的方式,eclipse中直接export即可,放到指定目录,此处放在

D:\jarload\test.jar


放好后,删除TestAction文件和package。

第四:写个main函数测试下 TestMain (这里比较无聊,写了个从文件读的方式获取jar路劲,路径就是上面提到的jar所在的位置)

package com.java.main;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.net.URL;
import java.net.URLClassLoader;

import com.java.loader.AbstractAction;
import com.java.loader.AbstractAction;


/**
 * 
 * 两种方式
 *
 */

public class TestMain {

	public static void main(String[] args) {
		try {
			//第一种  配置成文件格式
			File file = new File("D:\\jarload\\test.txt");
			BufferedReader in = new BufferedReader(new FileReader(file));
			String s = new String();
			while ((s = in.readLine()) != null) {

				URL url = new URL(s);
				s = null;
				
				URLClassLoader myClassLoader = new URLClassLoader(new URL[] { url }, Thread.currentThread()
						.getContextClassLoader());
				Class<? extends AbstractAction> myClass = (Class<? extends AbstractAction>) myClassLoader.loadClass("com.java.jarloader.TestAction");
				AbstractAction action = (AbstractAction) myClass.newInstance();
				String str = action.action();
				System.out.println(str);
				
				//第二种
				URL url1 = new URL("file:D:/jarload/test.jar");
				URLClassLoader myClassLoader1 = new URLClassLoader(new URL[] { url1 }, Thread.currentThread()
						.getContextClassLoader());
				Class<?> myClass1 = myClassLoader1.loadClass("com.java.jarloader.TestAction");
				AbstractAction action1 = (AbstractAction) myClass1.newInstance();
				String str1 = action1.action();
				System.out.println(str1);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}


第五:运行结果:

这是能完成运行的!

下面我们来改写下:

第一:将抽象类改成接口的形式  InterfaceAction 

package com.java.loader;

public interface InterfaceAction {
	public String action();
}

第二:改写下实体类,实现接口 TestAction

package com.java.jarloader;

import com.java.loader.InterfaceAction;

public class TestAction implements InterfaceAction{

	@Override
	public String action() {
		System.out.println("I am working ! ");
		return "this ActionTest class";
	}

}


第三步相同。

第四步:稍作修改 TestMain

package com.java.main;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.net.URL;
import java.net.URLClassLoader;

import javax.swing.AbstractAction;

import com.java.loader.InterfaceAction;




/**
 * 
 * 两种方式
 *
 */

public class TestMain {

	public static void main(String[] args) {
		try {
			//第一种  配置成文件格式
			File file = new File("D:\\jarload\\test.txt");
			BufferedReader in = new BufferedReader(new FileReader(file));
			String s = new String();
			while ((s = in.readLine()) != null) {

				URL url = new URL(s);
				s = null;
				
				URLClassLoader myClassLoader = new URLClassLoader(new URL[] { url }, Thread.currentThread()
						.getContextClassLoader());
				Class<?> myClass = (Class<?>) myClassLoader.loadClass("com.java.jarloader.TestAction");
				InterfaceAction action = (InterfaceAction) myClass.newInstance();
				String str = action.action();
				System.out.println(str);
				
				//第二种
				URL url1 = new URL("file:D:/jarload/test.jar");
				URLClassLoader myClassLoader1 = new URLClassLoader(new URL[] { url1 }, Thread.currentThread()
						.getContextClassLoader());
				Class<?> myClass1 = myClassLoader1.loadClass("com.java.jarloader.TestAction");
				InterfaceAction action1 = (InterfaceAction) myClass1.newInstance();
				String str1 = action1.action();
				System.out.println(str1);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}


第五:运行结果相同。

### Nvidia-SMI 命令详解 Nvidia-SMI 是用于管理监控 NVIDIA GPU 设备的强大工具。该命令提供了多种功能来获取有关 GPU 显存的信息。 #### 动态监测 GPU 状态 为了实时监视 GPU 的运行状况,可以使用 `watch` 结合 `-n` 参数设置间隔时间来进行周期性的检测。例如每半秒更新一次显示: ```bash watch -n 0.5 nvidia-smi ``` 这允许用户持续跟踪 GPU 使用情况而不必手动重复输入命令[^2]。 #### 查看特定编号的 GPU 信息 如果系统中有多个 GPU 希望仅关注某一块卡,则可通过 `-i` 参数指定其 ID 号码。比如要查看第零号 GPU 的详情: ```bash nvidia-smi -i 0 ``` 此操作有助于多 GPU 环境下的精准管理。 #### 列举所有 GPU 及 UUID 当需要快速获得整个系统的 GPU 清单连同各自的唯一识别符 (UUID),应执行如下命令: ```bash nvidia-smi -L ``` 这对于配置文件记录或是脚本编程非常有用处。 #### 定期自动刷新报告 利用 `-l` 参数能够设定固定的轮询频率,默认情况下每隔五秒钟就会重新抓取打印最新的资源占用数据直到收到终止信号为止: ```bash nvidia-l 5 ``` 这种方式适合长时间无人值守的任务环境,在后台稳定提供最新状态反馈。 #### 获取详尽硬件参数 对于更深入的技术支持需求或者故障排查场景下,借助于带有 `-q` 标志位的形式可以获得更为全面详细的设备属性描述;同样地也可以配合 `-i` 来限定范围至单一目标实例上: ```bash nvidia-smi -q -i 0 ``` 上述方法能有效辅助开发者定位问题根源以及优化性能表现。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值