Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中,我想调用一个名为';foo';,但是';foo';这是一根绳子。我该怎么做?_Java_String_Oop_Function - Fatal编程技术网

在Java中,我想调用一个名为';foo';,但是';foo';这是一根绳子。我该怎么做?

在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

我有一个名为“foo”(object foo=new object())的对象。我想在另一个方法中调用这个对象,在这个方法中,我在签名中传递一个带有这个对象名称的字符串。如何使用表示对象名称的字符串来调用此对象

我遇到找不到符号错误

下面是一些代码:

//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);
    }