在Java中,我想调用一个名为';foo';,但是';foo';这是一根绳子。我该怎么做?
我有一个名为“foo”(object foo=new object())的对象。我想在另一个方法中调用这个对象,在这个方法中,我在签名中传递一个带有这个对象名称的字符串。如何使用表示对象名称的字符串来调用此对象 我遇到找不到符号错误 下面是一些代码:在Java中,我想调用一个名为';foo';,但是';foo';这是一根绳子。我该怎么做?,java,string,oop,function,Java,String,Oop,Function,我有一个名为“foo”(object foo=new object())的对象。我想在另一个方法中调用这个对象,在这个方法中,我在签名中传递一个带有这个对象名称的字符串。如何使用表示对象名称的字符串来调用此对象 我遇到找不到符号错误 下面是一些代码: //from main method Object foo = new Object(); Monitor monitor = new Monitor(); //end main method class Monitor { public M
//from main method
Object foo = new Object();
Monitor monitor = new Monitor();
//end main method
class Monitor {
public Monitor() {
Manager manager = new Manager();
}
//IMPORTANT - info.objectName is user input, and for this example it is "foo"
public void processArgument(Instruction info) {
if (info.command == "read") int value = manager.read(info.objectName);
}
}
class Manager {
public int read(String obj) {
return obj.getRead();
}
}
class Object {
private int value;
public int getRead() {return value;}
}
我希望这是有道理的,我不是很擅长这个,但我需要一些帮助。这是针对一个具有严格反代码共享策略的类的,所以我尽量将其抽象化。简短回答
Java或JVM中不支持这一点
答案很长,为什么
给定MyCustomObject xxx=新的MyCustomObject()代码>
没有办法实际调用xxx
上的任何方法,这是对Java中MyCustomObject
类型的实例的引用,给定String s=“xxx”代码>。因为无法在JVM中搜索名为xxx
的引用。没有任何方法允许您在给定任意字符串的情况下查找引用xxx
重复问题
如果您无法通过引用名称找到它,则无法对其调用任何方法
棘手的解决办法
您可以将此引用存储在某种类型的Map
结构中,然后传递该结构并自己搜索,但这不是JVM或语言本身内置的任何内容。要实现这一点几乎是不可能的,它会给一些静态数据引入紧耦合,而许多其他糟糕的设计会导致很多麻烦。如果你想调用一个名为“foo”的方法
获取包含foo方法的类对象
调用getDeclaredMethod(),它返回Method对象
调用调用thw方法对象上的方法
您可能想看看反射API
有两种方法可以在本地实现这一点,还有一种方法不太本地
- 如果语句
- 函子映射
- 倒影
选择1
你所拥有的是选项1,它基本上是正确的,你只是使用了错误的比较方式。比较你的
public void processArgument(Instruction info) {
// this is bad - uses reference comparison
if (info.command == "read")
int value = manager.read(info.objectName);
}
与推荐的
public void processArgument(Instruction info) {
// this is good - actually compares the values
if (info.command.equals("read"))
int value = manager.read(info.objectName);
}
有些人认为执行下面的操作会更好,因为如果<代码>信息>命令<代码>为null,这不会引发异常。就我个人而言,我不喜欢这样,因为我宁愿得到例外,但许多人主张这样做,他们有一个完全合理的理由这样做
public void processArgument(Instruction info) {
// "read" can never be null, so no null pointer exception here
if ("read".equals(info) )
int value = manager.read(info.objectName);
}
当然,当您添加更多的行为时,您只需添加更多的if语句
在Java 7中,可以执行以下操作:
public void processArgument(Instruction info) {
switch(info.command) {
case "read": manager.read(info.objectName); break;
case "write": manager.write(info.objectName); break;
default: throw new IllegalArgumentException("Command " + info.command + " not supported");
}
}
选择2
另一种选择是使用使用匿名类的映射,如下所示:
// define this somewhere
abstract class Functor {
Manager m;
Functor(Manager m) { this.m = m; }
void execute(Instruction info);
}
// somewhere you have access to
Map<String,Functor> funcs = new HashMap<String,Functor>();
// add this to a static block, or constructor, depending
funcs.put("read", new Functor(manager) {
public void execute(Instruction info) { m.read(info.objectName); }
});
funcs.put("write", new Functor(manager) {
public void execute(Instruction info) { m.write(info.objectName); }
}
选择3
使用萨加达巴斯在他的文章中概述的反射。请注意,这可能需要特殊的访问权限,并且不会给您提供灵活的正确性选项。Uh,“什么”?请显示代码..foo是在什么上下文(范围)中定义的?这个作用域与您希望使用字符串“foo”调用它的上下文有什么关系?这是无法做到的。听起来您需要一个映射图
,但如果没有看到用例,就很难知道是否有更好的选项。@在某些语言中(但不是Java,至少是直接的),您可以执行$foo=new Object()之类的操作$name=“foo”$$名称->方法();如果OP用于编写脚本语言,这是有意义的。@yshavit如果foo是类成员,那么如果实例已知或是静态成员,则可以使用反射。
// define this somewhere
abstract class Functor {
Manager m;
Functor(Manager m) { this.m = m; }
void execute(Instruction info);
}
// somewhere you have access to
Map<String,Functor> funcs = new HashMap<String,Functor>();
// add this to a static block, or constructor, depending
funcs.put("read", new Functor(manager) {
public void execute(Instruction info) { m.read(info.objectName); }
});
funcs.put("write", new Functor(manager) {
public void execute(Instruction info) { m.write(info.objectName); }
}
public void processArgument(Instruction info) {
Functor f = funcs.get(info.command);
if(f == null) throw new IllegalArgumentException("Operation " + info.command + " not supported");
f.execute(info);
}