我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

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

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

screw Maven插件方式运行时在编译打包时跳过执行的问题如何解决

今天小编给大家分享一下screw Maven插件方式运行时在编译打包时跳过执行的问题如何解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起
2023-07-05

如何重用第三方包中的结构,同时更改单个字段的编组行为?

php小编子墨在这里分享一个关于如何重用第三方包中的结构并更改单个字段编组行为的技巧。当我们使用第三方包时,有时候我们需要对其中的某个字段进行自定义编组。本文将介绍一个简单的方法,可以通过继承和重写的方式来实现这一目标,既能重用原有的结构,
如何重用第三方包中的结构,同时更改单个字段的编组行为?
2024-02-10

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录