首先,方法名不建议中文,其二,类名首字母要大写。
先说,要自动执行某个类的方法,这个方法是静态方法还是一般的方法呢?一般的方法,他是需要对象的,对象来自哪里呢?你怎么知道有没有导入某个类呢?
如果想某个类被加载后执行一个静态方法进行初始化,只执行一次,你可以使用静态代码块。
class TestClazz {
static {
// 这里的代码会在类被加载的时候执行一次,一般也就只会执行一次 // 他是静态的。}
}
如果你想让类创建对象的时候自动执行某个方法,你可以在构造方法里面做执行。
class TestClazz {
public TestClazz() {
testMethod();
}
public void testMethod() {
}
}
你可以通过继承来进行判断和调用,让每一个子类都具有这样的特点。
如果需要在反射中使用某个方法,你可以定义接口,接口中给出一个固定名字的方法,因此所有能够反射的类都应该具备这个接口,这样你可以检查类是否实现接口来判断是否能反射调用。如果是这样的话你应该对反射的调用的方法进行封装,作为一个静态方法来使用。
interface ITest {
void test();
}
class Test implements ITest {
public void test() {
}
}
class Util {
public static void invokeTest(Clazz target) {
if(!ITest.isAssignableFrom(target)){
// 不是ITest接口,不执行return;
}
ITest test = target.getConstructor().newInstance();
test.test();
}
}
如果你需要在某一个字段存在的时候就执行某个方法,你可以定义一个父类,所有需要实现此功能的类都需要继承他,父类中实现字段的检查以及方法的调用。
class TestParent {
public TestParent() {
List fields = this.getClass().getDeclaredFields();
for(Field field : fields) {
// 你可以检查字段的类型,字段的值,字段的接口等,判断是否需要调用其他方法。 }
}
}
public Test extends TestParent {
public Test test = null;
}
如果以上都不符合你的预期,我想大概就是设计的问题了,因为java几乎无法得到导入一个类的其他类。
看评论得知,你需要执行任意类的方法。
首先,我们需要得到类,通过“包扫描”做到这一点,具体的做法是这样:
我们需要知道当前运行的环境在jar包中还是在文件夹,文件夹的话,我们可以直接遍历文件夹,Jar包的话,用相应的Jar包处理类,然后获取文件名,替换掉当前文件夹名字,只留下包名和类名(包名和类名组成了类的全限定名,例如java.lang.String)但是这里全限定名中间是斜杠,不是点,所以你需要替换斜杠为点。
这样全限定名就有了,用Class.forName加载Class,这样全限定名对应的类就加载到了,现在可以获取到类名。
建立一个HashMap,键是类名,值是全限定名,存储所有扫描到的类。
接下来,解析你输入的内容。
首先判别是否有new ,有的话用Boolean记录一个Flag,待会去newInstance,然后用String的replace方法删除new,然后trim一下去掉空格。
接着使用正则表达式 [.] 拆分字符串(字符串的split方法),然后得到字符串数组,应该是这样的:第一个元素是类名,第二个是方法名和参数表。
通过类名可以从HashMap得到全限定名,通过全限定名可以得到class,待会用来反射。
接着处理方法名和参数表,用split方法,参数是 [(] 然后得到字符串数组,第一个元素是方法名,第二个是参数表,方法名存到字符串,接下来处理参数表。
参数表用replace替换掉右括号,用split方法,参数是 [,] 然后得到字符串数组,这就是参数数组了。
请注意:所有方法的参数务必以字符串为类型,不然你需要手动判断参数类型并且进行类型转换。
接下来是执行阶段,判断那个用来做Flag的Boolean,需要的时候newInstance创建对象,接着根据参数表的长度(因为类型都是String,所以都是string就行)和方法名称,从刚才的Class得到Method,然后对method进行invoke,获取结果。
以上就是大致思路。