簡體   English   中英

以編程方式確定Java實例的編譯類型

[英]Programmatically determining the compile-type of a java instance

說我有一個擴展java.lang.Object的類,如下所示:

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

您沒有指定何時要查找編譯時間類型。 從示例輸出中,我假設您想在運行時打印出編譯時類型。

update:)這是不可能的,除非您事先知道要使用的所有類型,否則必須手動進行。

如果知道只使用Object和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        
}

您可以看到,除了調用Person的構造函數外,沒有引用Person類型,因此丟失了變量three例如Person類型的信息。 另外,Java沒有內置的運算符可用於在編譯時捕獲變量的類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM