当前位置: 技术问答>java相关
java某方法在写代码时,如何得知运行时将要调用它的方法的名称及其所在类名?(很难的,请赐教,送您100)
来源: 互联网 发布时间:2015-04-12
本文导语: java某方法在写代码时,如何得知运行时将要调用它的方法的名称及其所在类名? 说明: 某方法doReturn()将会被很多很多方法所调用。而它的实现内容却与调用它的方法的名称有关,也就是说,调用者不同,实...
java某方法在写代码时,如何得知运行时将要调用它的方法的名称及其所在类名?
说明:
某方法doReturn()将会被很多很多方法所调用。而它的实现内容却与调用它的方法的名称有关,也就是说,调用者不同,实现的功能不同。因此,如何在写代码时就知道调用者的信息?????
说明:
某方法doReturn()将会被很多很多方法所调用。而它的实现内容却与调用它的方法的名称有关,也就是说,调用者不同,实现的功能不同。因此,如何在写代码时就知道调用者的信息?????
|
枚举所有方法名称恐怕是最糟糕的设计了,因为你要"硬编码(hard code)",并且繁琐,容易出错。我觉得"不同功能的实现"放在调用者(caller)一方,在被调用者(callee)这边调用调用者的实现。
解决方案简单描述:
1、所有将要调用某方法(doReturn())的类实现接口DiffenrentReturnable。
2、此接口有一方法(whatDifferent()),也就是不同的实现,所有的调用者要实现。
3、你现在要做的就是定义doReturn()接受一个参数,类型就是刚才定义的接口,伪码如下:
void doReturn(DifferentReturnable df) {
df.whatDifferent; //让调用者实现不同的功能
。。。
}
解决方案简单描述:
1、所有将要调用某方法(doReturn())的类实现接口DiffenrentReturnable。
2、此接口有一方法(whatDifferent()),也就是不同的实现,所有的调用者要实现。
3、你现在要做的就是定义doReturn()接受一个参数,类型就是刚才定义的接口,伪码如下:
void doReturn(DifferentReturnable df) {
df.whatDifferent; //让调用者实现不同的功能
。。。
}
|
import java.io.*;
import java.util.*;
import java.lang.reflect.*;
public class MakeTodayClass {
Date today = new Date();
String todayMillis = Long.toString(today.getTime());
String todayClass = "z_" + todayMillis;
String todaySource = todayClass + ".java";
public static void main (String args[]){
MakeTodayClass mtc = new MakeTodayClass();
mtc.createIt();
if (mtc.compileIt()) {
System.out.println("Running " + mtc.todayClass + ":nn");
mtc.runIt();
}
else
System.out.println(mtc.todaySource + " is bad.");
}
public void createIt() {
try {
FileWriter aWriter = new FileWriter(todaySource, true);
//aWriter.write("package com;");
aWriter.write("public class "+ todayClass + "{");
aWriter.write(" public void doit() {");
aWriter.write(" System.out.println(""+todayMillis+"");");
aWriter.write(" }}n");
aWriter.flush();
aWriter.close();
}
catch(Exception e){
e.printStackTrace();
}
}
public boolean compileIt() {
String [] source = {"-d","d:/",new String(todaySource) };
ByteArrayOutputStream baos= new ByteArrayOutputStream();
//new sun.tools.javac.Main(baos,source[0]).compile(source);
// if using JDK >= 1.3 then use
System.out.println(com.sun.tools.javac.Main.compile(source));
System.out.println("================"+new String(baos.toByteArray()));
return (baos.toString().indexOf("error")==-1);
}
public void runIt() {
try {
Class params[] = {};
Object paramsObj[] = {};
Class thisClass = Class.forName(todayClass);
Object iClass = thisClass.newInstance();
Method thisMethod = thisClass.getDeclaredMethod("doit", params);
thisMethod.invoke(iClass, paramsObj);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
import java.util.*;
import java.lang.reflect.*;
public class MakeTodayClass {
Date today = new Date();
String todayMillis = Long.toString(today.getTime());
String todayClass = "z_" + todayMillis;
String todaySource = todayClass + ".java";
public static void main (String args[]){
MakeTodayClass mtc = new MakeTodayClass();
mtc.createIt();
if (mtc.compileIt()) {
System.out.println("Running " + mtc.todayClass + ":nn");
mtc.runIt();
}
else
System.out.println(mtc.todaySource + " is bad.");
}
public void createIt() {
try {
FileWriter aWriter = new FileWriter(todaySource, true);
//aWriter.write("package com;");
aWriter.write("public class "+ todayClass + "{");
aWriter.write(" public void doit() {");
aWriter.write(" System.out.println(""+todayMillis+"");");
aWriter.write(" }}n");
aWriter.flush();
aWriter.close();
}
catch(Exception e){
e.printStackTrace();
}
}
public boolean compileIt() {
String [] source = {"-d","d:/",new String(todaySource) };
ByteArrayOutputStream baos= new ByteArrayOutputStream();
//new sun.tools.javac.Main(baos,source[0]).compile(source);
// if using JDK >= 1.3 then use
System.out.println(com.sun.tools.javac.Main.compile(source));
System.out.println("================"+new String(baos.toByteArray()));
return (baos.toString().indexOf("error")==-1);
}
public void runIt() {
try {
Class params[] = {};
Object paramsObj[] = {};
Class thisClass = Class.forName(todayClass);
Object iClass = thisClass.newInstance();
Method thisMethod = thisClass.getDeclaredMethod("doit", params);
thisMethod.invoke(iClass, paramsObj);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
|
SecurityManager有一个getClassContext()方法,如果只需要类名,可以考虑用这个,但你得自己extend一个SecurityManager,因为这个方法是protected。另外一个方法就是生成一个Exception,然后调printStackTrace(...),打印到字符串中,然后解析字符串,得到所有的类和方法。注意打印格式可能随JVM的不同而改变。
|
既然你运行的时候才能知道有什么类来调用你的方法,那么, bdsc 的方法我认为是最好的了,否则,即使你能够得到调用你方法的类名,你也需要在doReturn()方法中一一列举你的处理方法,如果突然要增加一个新的类来调用你的方法呢?怎么办,难到开发者还要通知你修改你的方法?与其这样,不如声明你的接口,在调用者的类中实现(可以让调用者继承这个接口或采用其它设计模式)。
|
换个思路吧,带参数调用这个方法,如:
doReturn(int invokeParameter)
方法里面根据不同的参数值做不同的事
doReturn(int invokeParameter)
方法里面根据不同的参数值做不同的事
|
多多利用OO的特性就可以搞定!
用instanceof也可以,但不推荐。
用反射也能实现,但反而麻烦了。
用instanceof也可以,但不推荐。
用反射也能实现,但反而麻烦了。
|
关于这类问题的解决方法,可以参考设计模式中的模板方法模式和Command模式
|
猫哥,我想如果能实现这个功能的话,答案一定在Java虚拟机规范中。我想,因为在进行函数调用时是使用的堆栈,那么可以通过堆栈找出相关的信息的。马上要吃饭了,下午再来看规范吧!
|
“但如何能做到一次编码,就能在不同jvm上都能解析得到类和方法名呢?”这个只能试验了,呵呵,sun的JVM间应该差别不大。总的来说,Java API没有这方面的功能,所以只能凑合了,要么就得用C了。
|
如果你发现自己漩入了一个几乎无法解决的漩涡,
那么就说明你最初的设计就出了问题!!
任何程序高手也不能让别人什么也不动就可以在自己这边搞定一切!!!
那么就说明你最初的设计就出了问题!!
任何程序高手也不能让别人什么也不动就可以在自己这边搞定一切!!!
|
同意bdsc(),用接口比较合适!
|
isinstanceof
|
public class XX
{
static void doReturn( Object obj )
{
if( obj instanceof XYZ )
....
....
}
}
很恶心得办法
{
static void doReturn( Object obj )
{
if( obj instanceof XYZ )
....
....
}
}
很恶心得办法
|
和这个主题有关吗?
|
doReturn(Object b)
{
b.getClass().getName()//??可以吗?
}
{
b.getClass().getName()//??可以吗?
}