2008-09-03 13 views
51

有沒有辦法找到在Java中運行的程序的名稱?主要方法的類將是足夠好的。如果你從主線程運行

StackTraceElement[] stack = Thread.currentThread().getStackTrace(); 
    StackTraceElement main = stack[stack.length - 1]; 
    String mainClass = main.getClassName(); 

當然,這僅適用於:

回答

45

試試這個。不幸的是,我不認爲有一個系統屬性,你可以查詢找出。

編輯:在@約翰米格的評論,這是一個好主意拉:

要擴大@jodonnell你也可以 得到所有堆棧跟蹤使用Thread.getAllStackTraces系統 () 。從 這你可以搜索所有堆棧 痕跡爲「主」線程 確定什麼是主類。即使您的課程不是在主線程中運行的 ,此 也會起作用。

+0

好招。一般來說,可以從main()調用它,所以在這一點上只有一個線程,但是如果從別處調用它,我們最好有這個線程問題... – PhiLho 2012-07-11 06:14:00

+4

有沒有保證主要thead當您嘗試從其他線程查找應用程序名稱時正在運行。主線程可以正常完成,其他後臺線程還沒有完成。不要認爲從主線程開始做這個技巧是合理的。 – 2012-09-06 06:59:23

3

也可以從命令行運行jps工具。聽起來像一個

jps -l 

會得到你想要的。

15

要擴展@jodonnell,您還可以使用Thread.getAllStackTraces()獲得系統中的所有堆棧跟蹤。從這裏您可以搜索main線程的所有堆棧跟蹤,以確定主類是什麼。即使你的類沒有在主線程中運行,這也可以工作。

+7

主線程可能停止運行,但應用程序仍然繼續(其他非守護進程線程)。這可能發生在許多GUI/Swing應用程序中,因爲常見的習慣用法是主線程在EDT上調用以創建第一幀然後終止。 – 2010-03-11 05:53:05

-5

或者你可以使用getClass()。你可以這樣做:

public class Foo 
{ 
    public static final String PROGNAME = new Foo().getClass().getName(); 
} 

然後PROGNAME將在Foo的任何地方可用。如果您在靜態情況下不是,它變得更容易,因爲你可以使用這個:

String myProgramName = this.getClass().getName(); 
+0

我不認爲這解決了這個問題。海報不知道哪個類包含Java啓動時調用的main方法(可能它是第三方庫的一部分)。 – 2011-03-13 11:41:53

+1

這根本沒有意義。只有當我知道'Foo'是主要類時它纔有用。但是,我不需要這樣做。 – maaartinus 2011-03-13 11:55:08

-3

試試這個:

Java類都有自己的階級(java.lang.Class中的類型)的靜態實例。

這意味着如果我們有一個名爲Main的類。 然後我們就可以通過 Main.class

如果你有興趣的名字只有一個,

字符串的className = Main.class得到它的類的實例。的getName();

2

用於訪問類對象,當你在一個靜態的背景下

public final class ClassUtils { 
    public static final Class[] getClassContext() { 
     return new SecurityManager() { 
      protected Class[] getClassContext(){return super.getClassContext();} 
     }.getClassContext(); 
    }; 
    private ClassUtils() {}; 
    public static final Class getMyClass() { return getClassContext()[2];} 
    public static final Class getCallingClass() { return getClassContext()[3];} 
    public static final Class getMainClass() { 
     Class[] c = getClassContext(); 
     return c[c.length-1]; 
    } 
    public static final void main(final String[] arg) { 
     System.out.println(getMyClass()); 
     System.out.println(getCallingClass()); 
     System.out.println(getMainClass()); 
    } 
} 

顯然這裏的所有3個調用將返回

class ClassUtils 

,但你得到的圖片;

classcontext[0] is the securitymanager 
classcontext[1] is the anonymous securitymanager 
classcontext[2] is the class with this funky getclasscontext method 
classcontext[3] is the calling class 
classcontext[last entry] is the root class of this thread. 
8

這是我在使用jodonnell和John Meagher的組合響應時提出的代碼。它存儲的主類的靜態變量,以減少重複調用的開銷:

private static Class<?> mainClass; 

public static Class<?> getMainClass() { 
    if (mainClass != null) 
    return mainClass; 

    Collection<StackTraceElement[]> stacks = Thread.getAllStackTraces().values(); 
    for (StackTraceElement[] currStack : stacks) { 
    if (currStack.length==0) 
     continue; 
    StackTraceElement lastElem = currStack[currStack.length - 1]; 
    if (lastElem.getMethodName().equals("main")) { 
     try { 
     String mainClassName = lastElem.getClassName(); 
     mainClass = Class.forName(mainClassName); 
     return mainClass; 
     } catch (ClassNotFoundException e) { 
     // bad class name in line containing main?! 
     // shouldn't happen 
     e.printStackTrace(); 
     } 
    } 
    } 
    return null; 
} 
16
System.getProperty("sun.java.command")