Java反射、动态加载(将java类名、方法、方法参数当做参数传递,执行方法)
Class c = null;
try {
c = Class.forName(classname);
} catch (Exception e) {
e.printStackTrace();
}
Object o = c.newInstance();//创建实例
classname由包名+类名组成,例如com.xx.logic.Testclass,一定要写包名全路径,否则有可能报错找不到类
Class c=Class.forName(classname);
c.newInstance()
Class c=Class.forName(classname);
c.getConstructor(String.class).newInstance(“Hello”);
getConstrutor里面为构造参数的Class类型,多个入参时传递Class[]数组
newInstance里为具体要传递的参数值
Method m = c.getMethod(methodname, paramstype);
m.invoke(o, params);
public static void main(String args[]) {
// new Eeflect().runMethod("util.hi", "test",new Object[]{});//不带参数的方法调用
// new Object[]{}
new Eeflect().runMethod_classinstance(new hi(), "test2", "1,int:2");//传递一个实例,去执行方法
new Eeflect().runMethod("util.hi", "add", new Object[]{"1", "2"});//带参数的方法调用,但是变量是固定的
new Eeflect().runMethod_classname("util.hi", "test", "");//不带参数的方法
new Eeflect().runMethod_classname("util.hi", "add", "1,2");//String类型的方法
new Eeflect().runMethod_classname("util.hi", "test2", "1,int:2");//String和int两种类型的方法
System.out.println(new Object[]{}.getClass() );
new Eeflect().runMethod_classname("util.hi", "print", "StringArrays:1、2、3");//不固定参数...的方法,使用数组传递 }
package util; import java.lang.reflect.Method;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map; //动态执行方法,但是不能调用方法的方法
//getparam_valueandetype():解析参数,分解为参数值和参数类型数组
//runMethod_classname():传递类名,自动实例化执行方法
//runMethod_classinstance():传递类实例,执行方法 public class Eeflect {
public Class getClass(String classname) {
// URLClassLoader classloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class c = null;
try {
c = Class.forName(classname);
// c = classloader.loadClass(classname);
} catch (Exception e) {
e.printStackTrace();
}
return c;
} public Map getparam_valueandetype(String params) {//入参字符串,将其解析为参数class类型数组和参数值数组
//params使用英文逗号隔开,使用:分隔参数类型和值,例如abcd,int 1,test,int:2,StringArrays:1、2、3
Object[] paramlist = new Object[]{};//存储变量值
Class[] classtype = new Class[]{};//存储变量类型 Map result = new HashMap();
if (!params.equals("")) {//传递了参数params走这里
String[] paramslist_temp = params.split(",|,");
int num = paramslist_temp.length;
paramlist = new Object[num];
classtype = new Class[num];
for (int i = 0; i < num; i++) {
String[] param_type_value = paramslist_temp[i].toString().split(":");//判断参数是否有类型定义
if (param_type_value.length > 1) {
String param_type = param_type_value[0];
String param_value = param_type_value[1];
if (param_type.equalsIgnoreCase("int")) {
// System.out.println("value=" + param_value);
paramlist[i] = Integer.parseInt(param_value);
classtype[i] = int.class; } else if (param_type.equalsIgnoreCase("string")) {
paramlist[i] = param_value;
} else if (param_type.equalsIgnoreCase("stringarrays")) {
paramlist[i] = param_value.split("、");
classtype[i] = String[].class;
} else {
System.out.println("变量类型不支持,目前只支持int强转,当前变量的类型为:" + param_type);
return result;
}
} else { paramlist[i] = paramslist_temp[i];
classtype[i] = paramslist_temp[i].getClass();
}
}
} result.put("paramlist", paramlist);
result.put("classtype", classtype); return result;
} public boolean runMethod_classname(String classname, String methodname, String params) {//传递classname字符串,执行方法
boolean result = false;
Map paraminfo = this.getparam_valueandetype(params);
if (paraminfo == null) {
return result;
}
Object[] paramlist = (Object[]) paraminfo.get("paramlist");
Class[] classtype = (Class[]) paraminfo.get("classtype"); result=this.runMethod(classname, methodname, paramlist, classtype);
return result;
} public boolean runMethod(String classname, String methodname, Object[] params, Class[] paramstype) {//通过类名获得类实例,去执行方法
boolean result = false;
try {
Class c = this.getClass(classname);
if (c != null) {
Object o = c.newInstance();
Method m = c.getMethod(methodname, paramstype);
m.invoke(o, params);
result = true;
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
} public boolean runMethod_classinstance(Object classinstance, String methodname, String params) {//传递class实例,执行方法
boolean result = false;
Map paraminfo = this.getparam_valueandetype(params);
Object[] paramlist = new Object[]{};
Class[] classtype = new Class[]{};
if (paraminfo != null) {
paramlist = (Object[]) paraminfo.get("paramlist");
classtype = (Class[]) paraminfo.get("classtype");
} result = this.runMethod_hasclass(classinstance, methodname, paramlist, classtype); // if(!result){
// System.out.println("runMethod_classinstance失败了");
// }
return result;
} public boolean runMethod_hasclass(Object classinstance, String methodname, Object[] params, Class[] paramstype) {//通过类实例,去执行它的方法
boolean result = false;
try {
Class c = classinstance.getClass();
Method m = c.getMethod(methodname, paramstype);
m.invoke(classinstance, params);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
} public boolean runMethod(String classname, String methodname, Object[] params) {
boolean result = false;
try {
Class paramlist[] = null;
if (params != null) {//
int len = params.length;
paramlist = new Class[len];
for (int i = 0; i < len; ++i) {
paramlist[i] = params[i].getClass();
if (paramlist[i].toString().equals("class java.lang.Integer")) {
paramlist[i] = int.class;
}
}
} Class c = this.getClass(classname);
if (c != null) {
Object o = c.newInstance();
Method m = c.getMethod(methodname, paramlist);
m.invoke(o, params);
result = true;
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
Java反射、动态加载(将java类名、方法、方法参数当做参数传递,执行方法)的更多相关文章
- java反射动态加载类Class.forName();
1,所有的new出来的对象都是静态加载的,在程序编译的时候就会进行加载.而使用反射机制Class.forName是动态加载的,在运行时刻进行加载. 例子:直接上两个例子 public class Ca ...
- java反射--动态加载
Class.forName("类的全称") 1)不仅表示类的类类型,还表示了动态加载类 2)请区分编译,运行 3)编译时刻加载类是静态加载类,运行时刻加载类是动态加载类 比如下面: ...
- 透过现象看本质:Java类动态加载和热替换
摘要:本文主要介绍类加载器.自定义类加载器及类的加载和卸载等内容,并举例介绍了Java类的热替换. 最近,遇到了两个和Java类的加载和卸载相关的问题: 1) 是一道关于Java的判断题:一个类被首次 ...
- C# 利用反射动态加载dll
笔者遇到的一个问题,dll文件在客户端可以加载成功,在web端引用程序报错.解决方法:利用反射动态加载dll 头部引用加: using System.Reflection; 主要代码: Assembl ...
- .Net Core利用反射动态加载类库的方法(解决类库不包含Nuget依赖包的问题)
在.Net Framework时代,生成类库只需将类库项目编译好,然后拷贝到其他项目,即可引用或动态加载,相对来说,比较简单.但到了.Net Core时代,动态加载第三方类库,则稍微麻烦一些. 一.类 ...
- [改善Java代码]动态加载不适合数组
上一个建议解释了为什么要使用forName,本建议就说说哪些地方不适合使用动态加载. 如果forName要加载一个类,那它必须是一个类------8中基本类型就排除在外.它们不是一个具体的类. 其次它 ...
- Java的动态加载及其安全性问题
1.什么是动态加载 Class Loaders是动态加载Java类与Resource的一种机制.它支持Laziness,type-safe linkage,user-defined extensibi ...
- [转载] Java中动态加载jar文件和class文件
转载自http://blog.csdn.net/mousebaby808/article/details/31788325 概述 诸如tomcat这样的服务器,在启动的时候会加载应用程序中lib目录下 ...
- java动态加载jar包,并运行其中的类和方法
动态加载jar包,在实际开发中经常会需要用到,尤其涉及平台和业务的关系的时候,业务逻辑部分可以独立出去交给业务方管理,业务方只需要提供jar包,就能在平台上运行. 下面通过一个实例来直观演示: 第一: ...
- Java实现动态加载读取properties文件
问题: 当我们使用如下语句加载.properties时: ClassLoader classLoader = this.getClass().getClassLoader(); Properties ...
随机推荐
- 《算法》第四章部分程序 part 18
▶ 书中第四章部分程序,包括在加上自己补充的代码,在有权有向图中寻找环,Bellman - Ford 算法求最短路径,套汇算法 ● 在有权有向图中寻找环 package package01; impo ...
- 1. 在config.ini文件中加入dm.park.time=1,会使uap中的tomcat启动加快
在config.ini文件中加入dm.park.time=1,会使uap中的tomcat启动加快
- NDK samples以及部分博客
谷歌的ndk samples Android NDK samples with Android Studio http://developer.android.com/ndk 引用C/C++文件请参考 ...
- 表格线边框重复css解决方法
1.td 的边框和table 的边框重叠 .table { border-left:1px solid #dedede; border-top:1px solid #dedede;} .td { bo ...
- leetcode999
class Solution: def numRookCaptures(self, board: 'List[List[str]]') -> int: basei = 0 basej = 0 r ...
- nodejs 热更新插件
键入命令: npm -g install supervisor supervisor必须安装到全局 可以用supervisor 来启动服务 命令supervisor app.js
- Rocket MQ 问题排查命令
修改rocketmq官方代码测试: package com.alibaba.middleware.race.rocketmq; import java.util.Scanner; import com ...
- centos 下修改mysql 默认字符集
解决办法: CentOS 7下修改MySQL数据库字符编码为UTF-8,UTF-8包含全世界所有国家需要用到的字符,是国际编码. 具体操作: 1.进入MySQL控制台 mysql -u root - ...
- 【386】operator 的 itemgetter、slice、and_、or_
itemgetter 用来获取数组中指定索引的元素 from operator import itemgetter itemgetter(1, 3, 5)('ABCDEFG') output: ('B ...
- 【359】scikit learn 官方帮助文档
官方网站链接 sklearn.neighbors.KNeighborsClassifier sklearn.tree.DecisionTreeClassifier sklearn.naive_baye ...