代码之家  ›  专栏  ›  技术社区  ›  Dawid

“$0(程序名)在Java中?发现主类?“又来了

  •  2
  • Dawid  · 技术社区  · 14 年前

    我发现了以下问题: $0 (Program Name) in Java? Discover main class? 但在这种情况下,公认的答案是失败的:

    public class Derived extends Base { }
    
    class Base {
        public static void main(String[] args){
            System.out.println(getTheClassName());
        }
    
        static String getTheClassName(){
            StackTraceElement[] stack = Thread.currentThread().getStackTrace();
            StackTraceElement main = stack[stack.length - 1];
            return main.getClassName();
        }
    }
    

    呼叫时:

    java Derived
    

    不幸的是,输出是错误的 Base Derived 一如预期。

    真实的 主要课程?(顺便说一句。 jps

    致以最诚挚的问候。

    确切地说:我需要知道作为命令行参数传递给JVM的类的名称是什么。 工具按我想要的方式来做,但是由于其他问题(比如未知的VMid),我不能使用这个工具。

    编辑2: 全球回复 回答:

    对于您的工作方法,您需要一个非静态方法。成功 非静态,在派生中有一个main()执行一个新的派生()。getTheClassName()

    我想知道我不需要在派生类中实现main方法就可以得到这个名称。

    解决方案: 所有的答案都很有帮助。我接受了托比恩的回答,因为他比埃里克森更早地给出了答案。谢谢您。

    3 回复  |  直到 7 年前
        1
  •  5
  •   Thorbjørn Ravn Andersen    14 年前

    静态方法属于定义它们的类,而不是类的实例(与静态/非静态方法相同)。因此,当您在getTheClassName中时,您就在基类中定义的静态方法中。

    对于您的工作方法,您需要一个非静态方法。使其非静态,在派生中使用main()执行新的派生()。getTheClassName()

        2
  •  3
  •   erickson    14 年前

    Derived main 入口点在 Base static 属于他们的 不是遗传的。当按原样运行程序时,类 派生 甚至不会被加载,因为它从未被引用。


    考虑将派生类的名称作为 底座 班级。除了使目标类显式化之外,它可能是实现其他特性的一个方便的地方。

    class Base {
      public static void main(String... argv) throws Exception {
        Class<?> clz = Class.forName(argv[0]);
        Method mth = clz.getMethod("main", String[].class);
        String[] sub = new String[argv.length - 1];
        System.arraycopy(argv, 1, sub, 0, sub.length);
        mth.invoke(null, sub);
      }
    }
    
        3
  •  1
  •   Colin Hebert    14 年前

    试试这个:

    for(final Map.Entry<String, String> entry : System.getenv().entrySet()){
        if(entry.getKey().startsWith("JAVA_MAIN_CLASS"))
            return entry.getValue();
    }
    

    但你还是应该看看别人的答案。即使这样行得通,这也是一个非常糟糕的做法。