2009-06-29 74 views
0

以下是MainClass.java中列出的代碼。什麼是MyClass.class?

public class MainClass { 

    public static void main(String[] args) { 

     System.out.println("main started..."); 

     Class c = MyClass.class ; 
         //this class variable seems to be public static. 
         //But, as it is clearly visible in the MyClass, 
         //no reference variable is declared. 
         //My problem is that from where this class variable 
         //came from. 
         //i also check out the Object.java file, but it also don't 
         //have any public static class variable of Class class 
         //like there is 
         //out (instance of PrintStream class) in System class. 
         //Hope all u mindoverflow guys help me to sort out 
         //this probz. 

     try { 
      Class.forName(c.getName()) ; 

      System.out.println("classloader of MyClass : " + MyClass.class.getClassLoader()); 

      System.out.println("classloader of MyClass : " + String.class.getClassLoader()); 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } 

     System.out.println("main ended..."); 
    } 
} 

class MyClass{ 
    static{ 
     System.out.println("static block of MyClass class."); 
    } 
} 

日Thnx coobird ... 我發現文中非常有用。 :)

但是,關於litereals我的知識僅限於:

int i = 5 ; //here 5 is an integer literal 

float f = 5.6f ; //here 5.6f is a float literal 

唯一的非原始litereal,我所知道的是

String str = "java" ; //"java" is a String litereal 

和類文本,其中U和喬恩斯基特對我很清楚。

是否還有更多的文字在Java中找到?


同意...... 使每討論,總面值分爲以下幾類: -

  • 原始文字
  • 字符串文字
  • 類文本

是有一些文字(上榜的時間稍長:)


當我使用decomipler反編譯MainClass.class,二 類類型的靜態變量(可以!因爲,我已使用類文字2次)被發現自動添加,但從未發現在代碼中使用 。此外,這兩個類文字直接從我在java文件中使用它們的類文件中替換。

我的代碼: -

public class MainClass { 

    public static void main(String[] args) { 

     System.out.println("main started..."); 

     Class c = MyClass.class ; 

     try { 
      Class.forName(c.getName()) ; 

      System.out.println("classloader of MyClass : " + MyClass.class.getClassLoader()); 

      System.out.println("classloader of MyClass : " + String.class.getClassLoader()); 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } 

     System.out.println("main ended..."); 
    } 
} 

反編譯所生成的代碼: -

import java.io.PrintStream; 

public class MainClass 
{ 

    public MainClass() 
    { 
    } 

    public static void main(String args[]) 
    { 
     System.out.println("main started..."); 
     Class c = MyClass; 
     try 
     { 
      Class.forName(c.getName()); 
      System.out.println((new StringBuilder("classloader of MyClass : ")).append(MyClass.getClassLoader()).toString()); 
      System.out.println((new StringBuilder("classloader of MyClass : ")).append(java/lang/String.getClassLoader()).toString()); 
     } 
     catch(ClassNotFoundException e) 
     { 
      e.printStackTrace(); 
     } 
     System.out.println("main ended..."); 
    } 

    static Class class$0; 
    static Class class$1; 
} 
+0

null怎麼樣? – 2009-06-29 13:23:13

+0

true和false以及字符文字(char c ='\ n')怎麼樣?請參閱http://java.sun.com/docs/books/jls/third_edition/html/lexical .html#3.10爲文字類型的完整列表。 – 2009-06-29 16:58:33

+0

但列表沒有類字面值,爲什麼這樣? – mogli 2009-06-29 18:03:27

回答

9

這是「類字面量」 - 一種簡單的方法來獲取特定類型的Class<T>

有關更多詳細信息,請參閱Java語言規範的section 15.8.2

請注意,它不是該類的「字段」,它是一種特殊的語法糖。

由於類型擦除,您可能會遇到有關仿製藥的限制。 Guice中引入的TypeLiteral提供了更多信息和解決方法。

在實現方面,它取決於您定位的是哪個字節碼版本。如果使用-target 1.4(或更低版本),則將在調用類型初始化期間調用的靜態方法插入到代碼Class.forName()的調用中。如果您使用-target 1.5(或以上),則常量池將獲得「類」條目。我不知道如何處理這些細節。

3

寫入MyClass.class給出類型Class<MyClass>的對象。

所以,在上面的代碼,如果一個人正確使用仿製藥,應該寧可說:

Class<MyClass> c = MyClass.class; 

Class<?> c = MyClass.class; 

class關鍵字將給Class對象模型類。

正如喬恩斯基特提到的,The Java Language SpecificationSection 15.8.2: Class Literals說關於類字面以下:

類文字是由一個類的名稱的表達 , 接口,數組或基本類型, 或僞類型void,然後是 '。'和令牌class。 類文字的類型,C.Class,其中C是 名稱的類,接口或數組 類型,是Class<C>

通過當前實例的類的定義類加載器,類文字評估爲指定類型(或無效)的Class對象,定義爲 。

+0

但是隻有方法應該返回一些內容??? – mogli 2009-06-29 12:41:12

+0

好點,可能是它「返回」不是描述它的最好方法,我已經改變了措辭 – coobird 2009-06-29 12:49:17

0

要添加到別人已經說過,「MyClass.class」在語義上是相同的:

Class.forName("MyClass", false, classloader); 

其中「類加載器」是調用類的類加載器實例。

主要區別在於異常處理 - 上面的代碼片段引發了ClassNotFoundException異常,但我不相信MyClass.class可以拋出該異常(但它可能拋出ClassDefNotFoundError,但這是一個更一般的問題)。另外,MyClass.class使用import語句,而Class.forname()要求您傳入完全限定的類名稱。


正如我提醒的那樣,MyClass.class不初始化MyClass,因此不會調用靜態初始化程序。

0

對,沒有「class」實例變量可以這麼說。它實際上存在於每一個班級中。 MyClass.class直接爲MyClass獲取Class實例。我不確定你對反思有多熟悉,但是這可以讓你開始處理這個問題。您可以查看本教程以瞭解您可以執行的操作的一些示例: http://www.ibm.com/developerworks/library/j-dyn0603/

反射允許程序在運行時查看和修改它們自己的行爲。它是一種「元編程」。「