识别调用方法和参数而不进行反射

时间:2015-06-09 15:28:20

标签: java

我们说我有一个类如下面的方法

public class Parent {

    public boolean isValidURL() {
        System.out.println("print the name of the caller method and the method's arguements here");
        //pls ignore the return true below. just an eg.
        return true;
    }
}

然后我有另一个方法在父类中调用isValidURL

public class Child {
    Parent parent = new Parent();

    public void verifyURL(String url) {
        parent.isValidURL();
    }
}

现在在Parent类中,方法isValidURL()应该打印调用方法verifyURL()及其参数。

这可能没有反思吗?是否有需要遵循的设计模式?

编辑: 我想这样做是因为我想在记录器上实现这个想法。基本上,还有许多其他方法,如verifyURL()方法接受不同的参数。我希望有一个通用的记录器可以在“儿童”中使用任何方法在控制台上打印它。类被称为

4 个答案:

答案 0 :(得分:7)

  

这可能没有反思吗?

没有。 (我甚至认为 反射是可能的。)

  

是否需要遵循任何设计模式?

这里的模式是将相关信息作为参数传递给方法。 : - )

您还可以将Child的实例传递给Parent的构造函数,并将该网址存储为Child中的字段。

Parent parent = new Parent(this);  // ...then look up URL through field in Child

或者,您可以在调用isValidURL

之前使用setter
public void verifyURL(String url) {
    parent.setUrl(url);
    parent.isValidURL();
}

关于你的编辑:

  

编辑:我想这样做,因为我想在记录器上实现这个想法。基本上,还有许多其他方法,如verifyURL()方法接受不同的参数。当调用`Child'类中的任何方法时,我想有一个通用记录器在控制台上打印它

这清除了很多东西。

为此,我建议查看当前的堆栈跟踪。我在这里发布了一个类似的解决方案:

要记住健壮性,重要的是循环遍历堆栈跟踪,直到找到您要查找的元素。尽管Parent可以在内部委托调用或使用isValidUrl作为辅助方法,但很可能是感兴趣的调用类(在本例中为Child)。这是一个丢弃“内部”堆栈元素并打印调用类/方法名称的示例:

public boolean isValidURL() {
    for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
        if (ste.getClassName().equals(Thread.class.getName())
                || ste.getClassName().equals(getClass().getName()))
            continue;
        System.out.println(ste.getClassName() + "." + ste.getMethodName());
        break;
    }
    return true;
}

答案 1 :(得分:3)

这个答案基本上只是如何实现@LuiggiMendoza评论的一个例子。

(见这个答案:https://stackoverflow.com/a/421338/837703。)

您可以使用new Throwable().getStackTrace(),它或多或少等同于抛出异常时获得的堆栈跟踪类型。最近调用的方法将在索引0处,并且调用方法将(通常)位于索引1处。

因此,举例来说,您可以使errorlevel方法看起来像这样:

isValidURL()

...将打印出调用方法的名称和类的完全限定名称(在大多数情况下)。至于方法参数,您可以尝试使用日志记录,但这可能需要public boolean isValidURL() { StackTraceElement caller = new Throwable().getStackTrace()[1]; System.out.println(caller.getClassName() + "." + caller.getMethodName()); //pls ignore the return true below. just an eg. return true; } 类来记录它的参数,并且需要Child来获取它们。

答案 2 :(得分:0)

您似乎尝试重新创建跟踪日志记录。最好将Log4J用于此目的。然后在调用isValidURL之前在verifyURL方法中记录信息消息。

    public class Child {
        private static final Logger log = LoggerFactory.getLogger(Child.class);
        Parent parent = new Parent();

        public void verifyURL(String url) {
            log.info("verifyURL called");
            parent.isValidURL();
        }
    }

修改: 现在我读了你的问题编辑。您应该使用 AspectJ 来实现此目的。

寻找类似:http://www.yegor256.com/2014/06/01/aop-aspectj-java-method-logging.html

的内容

答案 3 :(得分:-1)

没有办法做到这一点。

你甚至试图这样做表明你的设计出了问题。

一种方法可能是使用模板模式。

public class Parent {

   public boolean isValidURL() {
      isValidURL( url );
      // do any other stuff necessary
   }

  public abstract isValidURL( String sURL );
}

当子类实现isValidURL方法时,它们会打印出任何必要的内容。