2014-04-07 32 views
1

說我有該擴展java.lang.Object如下一類:編程確定所述編譯類型的Java實例

package pack; 

public class Person { 

} 

和以下三個實例:

Object one = new Object(); 
Object two = new Person(); 
Person three = new Person(); 

爲了要確定運行時間類型,我只需要在實例上調用getClass()方法如下:

System.out.println("One runtime-type : " + one.getClass()); 
System.out.println("Two runtime-type : " + two.getClass()); 
System.out.println("Three runtime-type : " + three.getClass()); 

,輸出:

One runtime-type : class java.lang.Object 
Two runtime-type : class pack.Person 
Three runtime-type : class pack.Person 

現在的問題是如何以編程方式確定靜/編譯型上面的實例

通過靜態/編譯型我的意思是「左」的類型。它輸出:

One compile-type : class java.lang.Object 
Two compile-type : class java.lang.Object 
Three compile-type : class pack.Person 
+0

問題的更多鈔票dublicate:HTTP://計算器。com/a/3504894/1888799 – veysiertekin

+0

您能否提供您想爲此調用的方法的*方法簽名*? – Marco13

+0

你的用例是什麼?這隻有使用泛型類型,方法參數或對象屬性纔有意義。所有這些可以通過Java Reflection API進行更多或更少的提取。 http://docs.oracle.com/javase/tutorial/reflect/ –

回答

1

你沒當你想了解的編譯時類型指定。從您的示例輸出中,我假設您想要在運行時上打印編譯時類型。

這是不可能的,(更新:),除非你手動做它,知道你想要使用的所有類型事先。

如果你知道你將只使用對象和Person類,你可以試試下面的代碼。您需要爲每個使用的類定義一個方法,並且編譯器足夠聰明以使用最佳匹配方法。

public class Program { 
    static class Person { 
    } 

    public static void main(String[] params) throws Exception { 
     Object one = new Object(); 
     Object two = new Person(); 
     Person three = new Person(); 
     System.out.println("One compile-type : " + getStaticType(one)); 
     System.out.println("Two compile-type : " + getStaticType(two)); 
     System.out.println("Three compile-type : " + getStaticType(three)); 

    } 
    public static Class getStaticType(Person p) { 
     return Person.class; 
    } 
    public static Class getStaticType(Object o) { 
     return Object.class; 
    } 
} 

這會打印出:

One compile-type : class java.lang.Object 
Two compile-type : class java.lang.Object 
Three compile-type : class Program$Person 

需要注意的是,如果你想將它應用到界面,在這裏你可能會碰到的情況時,編譯器不能決定使用哪種方法,這種方法可能會斷裂。


原來的答覆:

你基本上是問什麼是類型在源代碼中的變量。運行時源代碼中唯一遺留的是Java編譯器生成的字節碼。該字節碼不包含任何有關變量類型的信息。

這裏是字節碼可以看起來像你的源代碼是什麼:

public static void main(java.lang.String[]) throws java.lang.Exception; 
    Code: 
     0: new   #2     // class java/lang/Object 
     3: dup   
     4: invokespecial #1     // Method java/lang/Object."<init>":()V 
     7: astore_1  
     8: new   #3     // class Program$Person 
     11: dup   
     12: invokespecial #4     // Method Program$Person."<init>":()V 
     15: astore_2  
     16: new   #3     // class Program$Person 
     19: dup   
     20: invokespecial #4     // Method Program$Person."<init>":()V 
     23: astore_3  
     24: getstatic  #5     // Field java/lang/System.out:Ljava/io/PrintStream; 
     27: new   #6     // class java/lang/StringBuilder 
     30: dup   
     31: invokespecial #7     // Method java/lang/StringBuilder."<init>":()V 
     34: ldc   #8     // String Two runtime-type : 
     36: invokevirtual #9     // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
     39: aload_2  
     40: invokevirtual #10     // Method java/lang/Object.getClass:()Ljava/lang/Class; 
     43: invokevirtual #11     // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder; 
     46: invokevirtual #12     // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
     49: invokevirtual #13     // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
     52: return   
} 

你可以看到,除了人的構造函數的調用,也沒有提及類型的人,因此該信息例如變量three是Person類型丟失的類型。此外,Java沒有任何內置的運算符,您可以在編譯時使用它來捕獲變量的類型。

+0

確實非常有趣......我在哪裏可以找到有關理解/讀取字節碼的參考/文檔? – balteo

+1

我認爲[javap文檔](http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javap.html)可能是一個很好的起點。 – Mifeet