Java 在父类中记录静态方法

Java 在父类中记录静态方法,java,static,log4j,Java,Static,Log4j,我有一个抽象类Parent,有两个子类A和B。Parent有一个静态方法do()。我想知道是否有一种方法可以让该静态方法在类a的Logger中添加日志信息(当它被称为a.do()时),以及在类B的Logger中添加日志信息(当它被称为B.do()时)。照常 protected final Logger LOGGER = Logger.getLogger(getClass()); 不会工作,因为do()是一个静态方法,所以记录器也需要是静态的,但是getClass()方法显然不是静态的 谢谢。最

我有一个抽象类Parent,有两个子类A和B。Parent有一个静态方法do()。我想知道是否有一种方法可以让该静态方法在类a的Logger中添加日志信息(当它被称为a.do()时),以及在类B的Logger中添加日志信息(当它被称为B.do()时)。照常

protected final Logger LOGGER = Logger.getLogger(getClass());
不会工作,因为do()是一个静态方法,所以记录器也需要是静态的,但是getClass()方法显然不是静态的


谢谢。

最佳做法是声明记录器为静态,例如

protected final static Logger LOGGER = Logger.getLogger(getClass());
通过这种方式,您可以使用动态和静态方法中的记录器

此外,每个类都应该有自己的记录器实例。所以我会改成私人的

另外,您应该调用“MyApp.class”,而不是调用“getClass()”


private final static Logger Logger=Logger.getLogger(A.class)


每个类都有自己的
记录器:指定类很好。

我不推荐它,但是如果你真的想要它

public class A {
  public static void do() {
    doImpl(A.class);
  }
  protected static void doImpl(Class<?> refClass) {
  }
}

public class B extends A {
  public static void do() {
    doImpl(B.class);
  }
}
公共A类{
公共静态void do(){
doImpl(A.class);
}
受保护的静态void doImpl(类refClass){
}
}
公共类B扩展了A{
公共静态void do(){
doImpl(B.class);
}
}

为什么该方法是静态的?使其非静态。@Sudhanshu-为什么需要抽象方法
getClass
?这已经内置到每个对象中。感谢您的回复。移除静态是显而易见的方法,但我希望它保持不变,因为该方法与该类的任何实例无关,而是与该类本身相关。@jtahlborn My bad,只是跳过了这一点。您是对的,它不是必需的。A.do()不能解析为Parent.do(),“当它被称为A.do时”没有意义。添加更多代码以澄清您想要的内容。谢谢您的回答。不幸的是,这也不起作用,因为使用记录器的静态方法位于父类中。每次调用它时,无论从何处调用,它都将使用父记录器,而不是子类的记录器。请允许我坚持:):每个类都应该声明自己的记录器、父类和子类。您不继承logger。我同意您的观点,每个类都应该有一个logger。因此,即使每个类都有一个记录器,您将如何使它使父类中存在的静态方法将信息记录在子类记录器中?等等。子类不使用父记录器。它有自己的记录器并使用它。因此,当您在child B中调用
log.info(…)
时,您实际上使用了在B顶部声明的最终静态记录器,该记录器记录在category
B.class
中,因此您的日志包含正确的类别/类名。或者我们在这里混淆了子类和类实例吗?那么您不能有静态记录器,或者您必须覆盖B中的do(),但是。。。好消息是,好的日志框架(如log4j)会报告类别为com.mycompany.A,但类为com.mycompany.B,因为类是在运行时确定的(尽管这是一个昂贵的调用,所以它实际上取决于调用的位置和方式)嘿!看起来这可能行得通:D,但我也不会这么做。因此,您认为我说我的备选方案如下是正确的吗:a)只需将静态方法记录在父类中。b) 复制所有子类中的整个静态方法c)使该方法不static@sakiskaliakoudas-我同意a,c。如果你打算做b,我会推荐我上面的答案。但是,是的,这些都是你的选择。@sakis kaliakoudas我已经用示例更新了我的答案如何为记录器引用你的类名(这是log4j创建者的最佳实践),这意味着所有内容都写在该类的记录器中,在你的示例中,“MyApp.class”,当方法调用来自子类时,我希望在子类中编写一些东西。每个类都应该使用自己的记录器实例。在子类中,不要使用父记录器。。。而是使用类中定义的当前记录器…这是Java中的标准实践。有关此主题,您可以从log4j文档中阅读更多内容:
public class A {
  public static void do() {
    doImpl(A.class);
  }
  protected static void doImpl(Class<?> refClass) {
  }
}

public class B extends A {
  public static void do() {
    doImpl(B.class);
  }
}