返回顶部
首页 > 资讯 > 精选 >如何改变jar包某个类的运行方式
  • 582
分享到

如何改变jar包某个类的运行方式

2023-06-17 13:06:53 582人浏览 泡泡鱼
摘要

这篇文章主要介绍“如何改变jar包某个类的运行方式”,在日常操作中,相信很多人在如何改变jar包某个类的运行方式问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何改变jar包某个类的运行方式”的疑惑有所帮助!

这篇文章主要介绍“如何改变jar包某个类的运行方式”,在日常操作中,相信很多人在如何改变jar包某个类的运行方式问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何改变jar包某个类的运行方式”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

例如:

有类 Feature

Java代码

public class Feature {             private String content;             public void show() {             System.out.println(this.content);         }     }

及类 Function

Java代码

public class Function {             private Feature f;             public void show() {             this.f.show();         }              }

测试类 Test,运行结果为 null . 而你想让他输出hello kitty

Java代码

public class Test {                     public static void main(String[] args) {             Function function = new Function();             function.show();         }         }

***想到的方法是就是直接建一个同包同名类,在你的eclipse或者其它编译环境下;然后把相关方法,改成自己想要的方法;如下:

Java代码

public class Feature {             private String content;             public Feature(){             this.content = "hello kitty";         }             public void show() {             System.out.println(this.content);         }     }

然后,你会发现,使用的是你的class吖,而不是jar包里的吖.

但是,如果你的程序也打成jar包,和原jar一起运跑,会是什么情况呢;

你可能发现,会输出 空,如果运气好,也可能 输出 hello kitty ;

为啥呢? 因为当有同包同名类时,classLoader总会尝试先加载到一个,而且加载到这个class文件后,后面就不会再加载;这个先加载到的类一般和classpath设置的先后有关;

在eclipse环境下,会先加载编辑器下的类,然后优先加载,先导入的类库;

如果先加载到你的类,那么就会输出 "hellokitty".

假如需要在生产环境指定加载你的类,

而且,

你无法预知客户如何设置classPath的先后顺序,那么,要怎么办呢?

可否自己写一个classLoader只加载目标类,而让你的调用程序在此classLoader环境下运行?

Let us try try : 先写出这个特别的classLoader

Java代码

public class HoneyLoader extends URLClassLoader {             public HoneyLoader(URL[] urls, ClassLoader parent){             super(urls, parent);         }             public synchronized Class loadClass(String name) throws ClassNotFoundException {             Class c = findLoadedClass(name);             if (c != null) {                 return c;             }     //先自己在指定位置(通过urls指定)找,找不到交给父类             try {                 c = this.findClass(name);             } catch (Exception e) {                 c = super.loadClass(name);             }             return c;         }     }

回到我们的测试类,修改如下

Java代码

public class Test {             public static void main(String[] args) throws Exception {             // 根据jar包名称,获取我们需要的jar包的名称的url             String jarName = "feature2.jar";             URL url = null;                 ClassLoader loader = Thread.currentThread().getContextClassLoader();             Enumeration urls = loader.getResources("Feature.class");             int i = 0;             while (urls.hasMoreElements()) {                 url = urls.nextElement();                 i = url.getPath().indexOf(jarName);                 if (i > -1) {                     break;                 }             }                 // 用honeyLoader启动我们的运行环境             ClassLoader myLoader = new HoneyLoader(new URL[] { new URL(url.getPath().substring(0, i) + jarName) }, loader);             Object object = myLoader.loadClass("Feature").newInstance();             object.getClass().getMethod("show").invoke(object);             }

运行结果:

Java代码

hello kitty

用classLoader的方法,将建立一个小的运行机制,和业务代码的相关性很低,冗余代码多;

而且,新建的和原类相同的包名和类不便于维护;

有什么更好的方法么?

对于(一)中描述的需求,其实,我们只需改变下Feature的私有属性content,是否可以通过反射来实现呢?

尝试以下代码:

Java代码

public class Test {             // 获取object 的属性 fieldName         public static Field getField(Object object, String fieldName) throws Exception {             Field field = object.getClass().getDeclaredField(fieldName);             return field;         }             public static void main(String[] args) throws Exception {             Function function = new Function();             // 获取function的feature             Field f_feature = getField(function, "f");                 // 通过feature 获取 其属性 content             f_feature.setAccessible(true);             Field f_function = getField(f_feature.get(function), "content");                 // 改变content的内容             f_function.setAccessible(true);             f_function.set(f_feature.get(function), "hello kitty");                 function.show();         }     }

执行,得到结果

Java代码

hello kitty

冗余代码减少,目的更加明确了,但对于改变的业务代码,任然不清晰;不容易维护;

通常,如果我们要得到有我们的特性的类,通常用继承的方法,但是有时候,会发现,如果是你要调用的调用的调用的类,要改变一点动作,那你为了改调用的调用的调用,不得不继承调用和调用的调用;

假如我们只改变目标类,只继承目标类,结合反射的方式,改调用,是否可行呢?

例如,继承Feature创建类MyFeature

Java代码

public class MyFeature extends Feature {             private String mycontent;             public MyFeature(){             this.mycontent = "hello kitty";         }             public void show() {             System.out.println(this.mycontent);         }     }

这样我们改变的逻辑清晰很多,容易维护,我们再来修改下Test类

Java代码

public class Test {             // 获取object 的属性 fieldName         public static Field getField(Object object, String fieldName) throws Exception {             Field field = object.getClass().getDeclaredField(fieldName);             return field;         }             public static void main(String[] args) throws Exception {             Function function = new Function();             // 获取function的feature             Field f_feature = getField(function, "f");                 // 改变feature的内容             f_feature.setAccessible(true);             f_feature.set(function, new MyFeature());                 function.show();         }     }

此时,Test的逻辑也清晰很多,我们可以清楚的看到,我们需要改变哪个类

运行一下,看下结果

Java代码

hello kitty

到此,关于“如何改变jar包某个类的运行方式”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: 如何改变jar包某个类的运行方式

本文链接: https://lsjlt.com/news/289353.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 如何改变jar包某个类的运行方式
    这篇文章主要介绍“如何改变jar包某个类的运行方式”,在日常操作中,相信很多人在如何改变jar包某个类的运行方式问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何改变jar包某个类的运行方式”的疑惑有所帮助!...
    99+
    2023-06-17
  • Linux 运行jar包的几种方式
    一、Linux 运行jar包的几种方式 方式一: java -jar xxx.jar 最常用的启动jar包命令,特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出 方式二: java -jar ...
    99+
    2023-09-12
    linux jar java Powered by 金山文档
  • Linux中jar包启动和jar包后台运行的实现方式
    linux 运行jar包命令如下: 方式一: java -jar shareniu.jar 特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出 那如何让窗口不锁定? 方式二 java ...
    99+
    2022-06-04
    linux jar包启动 linux jar包
  • 如何使用IDEA查看jar包,jar包的正确打开方式
    原理就用 IDEA 是把 jar 包添加为 Libraries,然后展开后即可查看。 因为是编译后的 class 文件,所以注释是没有的。 还有一种方法是把 jar 包的扩展名改为 rar,然后用压缩...
    99+
    2023-09-01
    intellij-idea jar java
  • react如何改变数组中的某个元素
    这篇“react如何改变数组中的某个元素”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“react如何改变数组中的某个元素”文...
    99+
    2023-07-04
  • Spring导出可以运行的jar包问题如何解决
    这篇文章主要介绍“Spring导出可以运行的jar包问题如何解决”,在日常操作中,相信很多人在Spring导出可以运行的jar包问题如何解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Spring导出可以运...
    99+
    2023-07-05
  • 详解如何更改SpringBoot TomCat运行方式
    1. 为什么要更改SpringBoot运行方式? Tomcat Connector(连接器)有三种运行模式:bio nio apr bio(blocking I/O) 即阻...
    99+
    2024-04-02
  • Vue如何用this.$set改变数组里的某个值
    Vue用this.$set改变数组里的某个值 <!DOCTYPE html> <html lang="en"> <head> <...
    99+
    2022-12-19
    Vue this.$set改变数组某个值 vue中this.$set()的用法 vue中this.$set()
  • linux如何查看某个进程的运行时间
    小编给大家分享一下linux如何查看某个进程的运行时间,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!查看某个进程的运行时间可能,大部分同学只会使用 ps aux,其实可以通过 -o 参数,指定...
    99+
    2023-06-27
  • 一文讲解如何获取k8s容器里运行的jar包
    目录01 引言02 从镜像信息获取03 进入容器获取(推荐)04 文末01 引言 在k8s上运行了第三方的应用,很多时候我们都想知道运行流程,一般都会从k8s容器中获取jar包。 那...
    99+
    2024-04-02
  • 如何将Java程序打包成一个可执行的jar文件包
    如何将Java程序打包成一个可执行的jar文件包?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。首先要确认自己写的程序有没有报错。第一次我写的是Web Project到现在,...
    99+
    2023-05-31
    java jar
  • 如何解决springboot项目打成jar包后运行时碰到的问题
    这篇文章主要介绍了如何解决springboot项目打成jar包后运行时碰到的问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。项目打成jar包后运行时的坑问题我的spring...
    99+
    2023-06-29
  • php如何改变页面的编码方式
    这篇文章主要介绍了php如何改变页面的编码方式的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇php如何改变页面的编码方式文章都会有所收获,下面我们一起来看看吧。一、了解什么是编码首先,我们需要了解什么是编码。编...
    99+
    2023-07-05
  • MySQL如何改变表的存储引擎方式
    目录1.最简单的方法是使用alter table语句2.导入导出3.创建与查询(create 和 select)总结1.最简单的方法是使用alter table语句 例如: alter table tablen...
    99+
    2023-11-22
    MySQL改变表 MySQL存储引擎 MySQL引擎
  • Java入门教程--带包的类如何编译与运行
    目录包机制概述带包的类如何编译与运行1.编译带包的类首先需要配置好环境变量2.配置好后在此输入 cmd 回车打开命令窗口3.输入 javac HelloWorld.java 回车进行...
    99+
    2022-12-23
    Java入门教程 Java带包编译 Java带包运行
  • R语言如何通过parallel包实现多线程运行方式
    这篇文章将为大家详细讲解有关R语言如何通过parallel包实现多线程运行方式,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。什么是R语言R语言是用于统计分析、绘图的语言和操作环境,属于GNU系统的一个自由...
    99+
    2023-06-14
  • 响应式编程如何改变Java中的索引数据类型?
    响应式编程是一种编程范式,它可以帮助我们更加优雅地处理异步事件流。在Java中,响应式编程已经成为了一种趋势,并且在Java 9中也加入了响应式流API。但是,响应式编程在处理索引数据类型方面,需要我们有一些新的思考方式。 Java中的索引...
    99+
    2023-09-09
    响应 索引 数据类型
  • screw Maven插件方式运行时在编译打包时跳过执行的问题如何解决
    今天小编给大家分享一下screw Maven插件方式运行时在编译打包时跳过执行的问题如何解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下...
    99+
    2023-07-05
  • 如何使用:focus伪类选择器改变表单元素的样式
    如何使用:focus伪类选择器改变表单元素的样式引言:在我们的网页设计中,表单元素是常见的交互组件,用户可以通过表单元素与网页进行交互。为了提升用户体验和界面美感,我们经常需要在用户与表单元素交互时改变其样式。本文将介绍如何使用:focus...
    99+
    2023-11-20
    表单 选择器 :focus
  • 如何实现查询某个用户过去一段时间内运行的SQL语句
    小编给大家分享一下如何实现查询某个用户过去一段时间内运行的SQL语句,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!with hi...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作