您没有指定何时要了解编译时类型。从您的示例输出中,我假设您想在运行时打印出编译时类型。
这是不可能的,(更新:)除非您手动执行此操作,并且事先知道您要使用的所有类型。
如果你知道你将只使用 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 没有任何内置运算符可用于在编译时捕获变量的类型。