- 浏览: 94928 次
- 性别:
- 来自: 杭州
最新评论
-
张希明:
...
js 正则匹配(去掉html标签) -
cuifuq7:
[img][/img][size= x-small] ...
java getMethod与invoke
前言:
了解Java的类装载器:
Java 编程语言编译器把源代码代码转换成为一个假定机器(即虚拟机)上的 机器语言。虚拟机代码保存在一个后缀为.class的类文件中。每个类文件保存这
个类的所有方法的虚拟机代码。
当运行时用一个解释程序解释这些类文件,把这些文件内的虚拟机指信信令翻 译成本地的机器语言,分存内存,确定程序入口点。
类装载器功能类似与C中调入dll文件文法,在C中是调入dll文件分配内存,确定 程序入口点(分配入口指针),而在java中调入一个class文件,同样是从本地或网络
中调入文件,转换为本地机器代码,分配内存,确定程序入口点。
当我们在使用中有时要使用一个新类,知道它的文件路径和它的文件名字,我们 要把它调入系统并使用它或者说一个类文件已经被加密处理,类文件里面的内容
是我们加密后的密文,不能直接使用,只能是对文件内容解密后才能使用,就可 以用类库加载器ClassLoader,把类文件当做数据流读入到一个byte[]中,对
这个 byte[]进行解密处理后(没加密当然就不用做这步了),再通过 byte[] 生成一个类,并加载到系统中。
对于使用中有以下两种方法:
-
方法1
使用接口类,新调用的class是对它的具体实现1) 写一个接口类 newface.class
public interface newface {
public void out(String xx);
public int outsize(String x1,String x2);
}
2) 写接口文件实现 testfacea.class 并更名为 testfacea.file 或其它文件名全可以
/*
newface的实现
*/
public class testfacea implements newface{
public void out(String xx) {
System.out.println(xx+" for testfacea ");
}
public int outsize(String x1,String x2) {
return x1.length()+x2.length();;
}
}
执行的的命令
javac testfacea.java
ren testfacea.class testfacea.file3) 在主程序中调入文件到byte[]中,可以在文件可以在本地,也可用网络无论如何只要能将编译后的文件内容的类代码放到 byte[]当中就可以
java.io.FileInputStream in=new java.io.FileInputStream(namefile);
byte[] classbyte=new byte[maxsize];
4) 转换成一个Class并初始化
return defineClass(classname,classbyte,0,readsize);
5) 实现接口
实际上就是对一个接口类用调入的文件实现,当然可以用不同的文件进行不同的实现也可以对一个文件进行加解密操作,
//方法 1 的例子代码,newface是本地接口类,newface.class本地已经存在 开始
testc=cl.load("testfacea.file","testfacea");
testo=testc.newInstance();
((newface)testo).out("方法1 第(1)种使用方法");
System.out.println("outsize="+((newface)testo).outsize("1111","aaaa"));
或
testc=cl.load("testfacea.fisle","testfacea");
testo=testc.newInstance();
newface newface1=(newface)testo;
newface1.out("方法1 第(2)种使用方法");
System.out.println("outsize="+newface1.outsize("22222","bbbbb"));
要注意的是对一个要调入的文件,一定要是一个已经存在的接口类的实现这个有点EJB中的调用的中远程接口要在本地,而调入的文件就是EJBobject了这种方法的的好处是要调入的class中的方法是可以说是已知的,相对来讲这种方法简明易用以下是主程序的完整代码
//使用的主程序
public class testnewface {
public static void main(String[] args) throws java.lang.Exception
{
// 共用初使化参数,开始
Class testc;
Object testo;
cloader cl=new cloader();
// 共用初使化参数,结束
//方法 1 的例子代码,newface是本地接口类,newface.class本地已经存在 开始
testc=cl.load("testfacea.file","testfacea");
testo=testc.newInstance();
((newface)testo).out("方法1 第(1)种使用方法");
System.out.println("outsize="+((newface)testo).outsize("1111","aaaa"));
testc=cl.load("testfacea.fisle","testfacea");
testo=testc.newInstance();
newface newface1=(newface)testo;
newface1.out("方法1 第(2)种使用方法");
System.out.println("outsize="+newface1.outsize("22222","bbbbb"));
//方法 1 的例子代码,结束
}
}
/*
要想自己完成从一个 byte[] 转换到一个Class 必须要 extends ClassLoader
因为ClassLoader中的方法defineClass是 protected 要使用只有 extends ClassLoader
*/
class cloader extends ClassLoader {
static int maxsize=10000;
public Class load(String namefile,String classname) throws java.lang.Exception
{
try {
//进行判断这个class是否已经调入,已经有就直接返回,不然就调入
Class ctmp=this.findLoadedClass(classname);
System.out.println(ctmp.getName()+" is load");
return ctmp;
}
catch (Exception e) {
//System.out.println(e);
}
java.io.FileInputStream in=new java.io.FileInputStream(namefile);
byte[] classbyte=new byte[maxsize];
//实际应用时完全可以对一个文件进行加解密处理,只要保证使用defineClass时classbyte中
//已经解密后的内容就可以
int readsize;
readsize=in.read(classbyte);
// System.out.println("读文件长:"+readsize);
in.close();
return defineClass(classname,classbyte,0,readsize);
}
}
-
方法2
不使用本地接口类的方法,这种方法class从文件定义成一个class和方法1是相同的,但要使用这个class就不同了,这种方法不需要接口类,1) 写一个类 testfacea.class (本例中为了方便还是使用了testfacea,实际上已经可以不用 implements
newface,即可以完全不用接口类)
public class testfacea {
public void out(String xx) {
System.out.println(xx+" for testfacea ");
}
public int outsize(String x1,String x2) {
return x1.length()+x2.length();;
}
}
为明析起见还有一个测试用类型:一个列系统信息表的类
public class listinfo {
public static void main(String[] args) {
//列系统信息表 begin
String skey,sinfo;
Object so;
java.util.Enumeration hlistkey=System.getProperties().propertyNames();
while (hlistkey.hasMoreElements())
{
skey=(String)hlistkey.nextElement();
so=System.getProperty(skey);
System.out.println("key="+skey+" info="+so);
}
//列系统信息表 end
}
}
2) 生成 testfacea.class 更名为 testfacea.file 或其它文件名也可以
生成 listinfo.class 更名为 listinfo.file 或其它文件名也可以
执行的的命令
javac testfacea.java
ren testfacea.class testfacea.file
javac listinfo.java
ren listinfo.class listinfo.file
3) 主程序中调入文件到byte[]中,可以在本地文件调用,也可用网络无论如何只要能将编译后的文件内容的类代码放到 byte[]当中就可以
java.io.FileInputStream in=new java.io.FileInputStream(namefile);
byte[] classbyte=new byte[maxsize];
4) 转换成一个Class
return defineClass(classname,classbyte,0,readsize);
5)如果调用的方法不是static,那么要初始化一个 Object
6) 用java.lang.Class 中的 getMethod(方法名,Class 类型的参数数组) 得到一个
java.lang.reflect.Method 就是说从一个class取到它的方法后调用这个方法
7 ) 使用java.lang.reflect.Method 中的 invoke(Object,new Object[]{参数1,参数2,...})
调用方法,invoke 返回一个Object,Object 的实际就是相应方法的返回类型,如果调用的方法不是static,那么Object
就放入初始化一个的Object,否则放一个 null 值8) 转换相应的类型到正确对应的Class
本方法要在写程序时已知要调入的class中的方法名,参数,返回类型和相应功能,相对来讲复杂一些
主程序代码:
*/
//使用的主程序
public class testnewface {
public static void main(String[] args) throws java.lang.Exception
{
// 共用初使化参数,开始
Class testc;
Object testo;
cloader cl=new cloader();
// 共用初使化参数,结束
//方法 2 的例子代码,开始
testc=cl.load("testfacea.fisle","testfacea");
testo=testc.newInstance();
String x="方法2 第(1)种使用方法--进行 Instance";
java.lang.reflect.Method mout=testc.getMethod("out",new Class[]{x.getClass()});
System.out.println("mout name="+mout.getName());
mout.invoke(testo,new Object[]{x});
String x1="33333",x2="cccccc";
java.lang.reflect.Method moutsize=testc.getMethod("outsize",new Class[]{x1.getClass(),x2.getClass()});
System.out.println("mout name="+moutsize.getName());
Integer xx=(Integer)moutsize.invoke(testo,new Object[]{x1,x2});
System.out.println(xx.intValue());
//方法(2) 不进行Instance,---调用了另外一个有main的类
testc=cl.load("listinfo.file","listinfo");
System.out.println("testc="+testc.getName());
java.lang.reflect.Method m=testc.getMethod("main",new Class[]{args.getClass()});
System.out.println("m="+m.getName());
m.invoke(null,new Object[]{args});
//方法 2 的例子代码,结束
}
}
/*
要想自己完成从一个 byte[] 转换到一个Class 必须要 extends ClassLoader
因为ClassLoader中的方法defineClass是 protected 要使用只有 extends ClassLoader
*/
class cloader extends ClassLoader {
static int maxsize=10000;
public Class load(String namefile,String classname) throws java.lang.Exception
{
try {
//进行判断这个class是否已经调入,已经有就直接返回,不然就调入
Class ctmp=this.findLoadedClass(classname);
System.out.println(ctmp.getName()+" is load");
return ctmp;
}
catch (Exception e) {
//System.out.println(e);
}
java.io.FileInputStream in=new java.io.FileInputStream(namefile);
byte[] classbyte=new byte[maxsize];
//实际应用时完全可以对一个文件进行加解密处理,只要保证使用defineClass时classbyte中
//已经解密后的内容就可以
int readsize;
readsize=in.read(classbyte);
// System.out.println("读文件长:"+readsize);
in.close();
return defineClass(classname,classbyte,0,readsize);
}
}
小结:
但是Java并不提供一个类似于类库卸载器(ClassUnloader) 的功能,能够把已经装载的模块从内存里面清除掉。所以如果一个class已经调入,就放在了内存当中,并在程序信息表内记录本class已经调入,如果再一次使用就从内存当中调入,如果实际文件更新也只能是程序下次运行时间再调入,而不能在运行期间更新一个class,如果强行再一次调入就会
Linkage Error: duplicate class definition (重复定义class) 所以在每次调用前用 findLoadedClass
方法进行一下判断。
发表评论
-
myeclipse
2012-09-18 17:19 736import java.io.*; public ... -
myeclipse6.0.1注册码生成代码
2012-09-13 09:44 6在csdn上看到的,高手就是不一样呀。 pack ... -
自定义一个exception
2012-08-31 16:27 803自己定义exception来对一些业务上的问题进行处理 ... -
在过滤器中对ignoreURL进行处理
2012-08-31 15:30 2303公司的框架提供了对页面表格的验证功能,但必须要通过 ... -
一个登陆验证的过滤器
2012-08-31 09:37 876import javax.servlet ... -
java getMethod与invoke
2012-07-17 08:25 19292这样写(假设方法的参数是String[],如main(Stri ... -
HashMap的两种排序方式
2012-07-16 16:52 755Map<String, Integer> map ... -
编写代码从文件系统中加载目标代码,并且运行
2012-07-15 16:39 1011... -
使用JFileChooser获得选择的文件路径
2011-07-10 21:09 11157private JFileChooser fc=new J ...
相关推荐
本例可实现文件的读写以及进度的保存和调入。
在Flash中,文本的调入是一项重要的功能,它允许开发者从外部源动态加载文本和图片,从而实现内容的更新和交互性。动态文本是相对于静态文本的一种,它可以在运行时改变,提供更灵活的显示效果。自动生成滚动条则是...
用java实现类似金山...从文件中调入英文录入材料,并将其显示 到图形界面的窗口中,然后根据用户的按键依次设置窗口中字符的颜色(正确为 12 绿色,错误为红色),用户打字结束后可以给出错误率,以及平均录入速度。
在企业信息化管理中,财务系统扮演着至关重要的角色,其中资产调入单是记录企业固定资产增减变动的重要凭证。本文将围绕"U9资产调入单单据类型"这一主题,深入探讨其在实际应用中的详细知识。 一、U9系统概述 U9是...
“调入时间”和“调出时间”记录了员工在不同岗位上的起止日期,这些信息对于计算工龄、绩效评估和确定福利待遇都有实际意义。 “调入原因”和“调出原因”是理解人员调动背后逻辑的关键,可能涉及企业发展需求、...
目录结构在文件管理中起着关键作用,从单级目录到多级目录(树形结构),再到无环目录结构,都是为了满足用户按名存取、提高检索速度、控制访问权限以及解决文件重名等问题。文件控制块(FCB)和索引节点是实现目录...
一个操作系统文件管理的小课设,采用javafx做...文件管理,由于系统的内存有限并且不能长期保存,故平时总是把它们以文件的形式存放在外存中,需要时再将它们调入内存。如何高效的对文件进行管理是操作系统实现的目标。
参考资料-U9库存调入单.zip
每个编写好的批处理文件都相当于一个DOS的外部命令,可以将它所在的目录放到DOS搜索路径(path)中来使得它可以在任意位置运行。 在DOS和Win9x/Me系统下,C:盘根目录下的AUTOEXEC.BAT批处理文件是自动运行批处理文件...
将acad文件导入到Google Earth中,可以让设计者和工程师在真实世界背景下查看他们的设计,这在规划、景观设计、建筑模拟等方面非常有用。 为了实现这个功能,我们需要一个转换工具,从描述中的"acad2kml3.0"来看,...
用户和系统要频繁地对它们进行访问,如果让用户在程序中自己安排它们在外存的存放位置,不仅要求用户熟悉外存的特性、各种文件的属性以及它们在外存上的位置,而且在多用户环境下,还必须保证数据的安全性和一致性。
系统硬盘中的MSDOS.SYS内容比较完整,包括必要的启动配置命令,文件长度必须大于1024 bytes,即占用两个以上磁盘扇区,这一要求在该文件中说明为保证兼容性,但从未见更深入的介绍,实际上文件小于1024 bytes对...
VBA(Visual Basic for Applications)是Microsoft Office套件中的一种编程语言,用于自动化和自定义工作流程,特别是在Excel中。本主题将深入探讨如何利用VBA来实现Excel表之间的自动数据调入,这对于大量数据管理...
- **文件存储位置**:文件通常存储在外部介质(如磁盘)上,使用时会被调入内存。 - **文件分类**: - **普通文件**:驻留在磁盘或其他外部介质上的有序数据集,包括源文件、目标文件、可执行程序等。 - **设备...
可以将批处理文件放到dos的搜索路径中,使得它可以在任意位置运行。也可以将批处理文件放到一个特定的目录中,以便于管理和维护。 五、批处理文件的应用 批处理文件可以应用于各种场景,例如自动运行命令、设置...
检索目录文件过程中只用到文件名,仅当找到一个目录项时才从该目录项中读出该文件的物理地址,而其它一些对该文件进行描述的信息在检索目录时不会用到,故这些信息不需调入内存。于是,可以将文件名和文件描述信息...
8日联合发布的反映沪深300指数编制目标和运行状况的金融指标,并能够作为投资业绩 的评价标准,为指数化投资和指数衍生产品创新提供基础条件。 公告日期:2005.4 .8-2023.12.11 包含字段 公告日期 变更日期 成份证券...
在 DOS 和 Win9x/Me 系统下,C:盘根目录下的 AUTOEXEC.BAT 批处理文件是自动运行批处理文件,每次系统启动时会自动运行该文件,可以将系统每次启动时都要运行的命令放入该文件中,例如设置搜索路径,调入鼠标驱动和...
问题描述:一个城市有若干公交线路,一个公交线路中的相邻两个站点需要运行的时间是已知的,假设在所有公交线路中任意两个相邻站点之间的耗时都是相同的,计算任意两个站点的最小时间。 基本要求: (1)建立城市的...