2009-06-29 8 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を、私は知っているuとジョンスキート、

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

とクラスリテラルであります私には非常によく分かります。

さらにリテラルがjavaにありますか?

  • プリミティブリテラル
  • 文字列リテラル
  • クラスリテラル
  • ヌル
  • - :


    は がそのような議論のとおり、総リテラルは以下のように分類され...合意しました

は、いくつかのより多くのリテラル(少し長いリストを作成する:)


私はdecomiplerを使用してMainClass.classをコンパイルするとき、2クラス タイプ静的変数が(だってすることができるが、私がありますクラスリテラルを2回使用しています)が自動的に追加されますが、コード内で が使用されていませんでした。また、両方のクラスリテラルは、私がjavaファイルで使用したクラスファイルから直接置き換えられます。

私のコード: - :MyClass.classはタイプClass<MyClass>のオブジェクトを与える書き方

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

ヌルについてはどうですか? –

+0

trueおよびfalse、および文字リテラル(char c = '\ n')はどうですか?http://java.sun.com/docs/books/jls/third_edition/html/lexicalを参照してください。 .html#3.10リテラルタイプの完全なリストについては –

+0

ですが、リストにはクラスリテラルがありません。なぜですか? – mogli

答えて

9

「クラスリテラル」は、特定のタイプのClass<T>を取得する簡単な方法です。

詳細については、Java言語仕様のsection 15.8.2を参照してください。

クラスの「フィールド」ではないことに注意してください。これは構文的な砂糖の特別な部分です。

タイプの消去のため、ジェネリックの周りに興味深い制限があります。 Guiceに紹介されたTypeLiteralは、より多くの情報と回避策を提供します。

実装の観点からは、どのバイトコードバージョンをターゲットにしているかによって異なります。 -target 1.4(またはそれ以下)を使用する場合は、Class.forName()への呼び出しが、型の初期化中に呼び出される静的メソッドでコードに挿入されます。 -target 1.5(またはそれ以上)を使用すると、定数プールは「クラス」エントリを取得します。私はこれがどのように処理されるかの詳細を知らない。

「クラスローダー」は、呼び出し元のクラスのClassLoaderインスタンスである
Class.forName("MyClass", false, classloader); 

:他の人がすでに言ったことに追加するには

+0

はSystem.outのような意味ですか? – mogli

+0

いいえ、System.outはコンパイラに関する限り通常のフィールドです。(It他の点では奇妙な性質を持っていますが、*言語*で扱われることはありません) –

+1

私はC#開発者としてJavaを少し気にかけているので、これをハイジャックします。 .netのtypeof(Class)? –

3

から

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..."); 
    } 
} 

逆コンパイラは、コードを生成しました。

1が正しくジェネリックを使用することであれば、上記のコードでは、それはむしろ言うべき:

Class<MyClass> c = MyClass.class; 

または

Class<?> c = MyClass.class; 

classキーワードはモデルClassオブジェクトを提供しますクラス。

ジョンスキートによって述べたように、The Java Language SpecificationSection 15.8.2: Class Literalsクラスについて以下リテラル言う:

クラスリテラルは、クラス、 インタフェース、配列、またはプリミティブ型の名前からなる発現 あります、 または疑似型の空白の後に 'が続きます。トークンはclassです。 クラスリテラルのタイプは、です。Cは、クラス、インターフェイス、または配列 タイプの の名前です。Class<C>です。

クラスリテラルは、 という名前の型(またはvoid)のClassオブジェクトに対して、現在のインスタンスのクラスの定義クラスローダーによって評価されます。

+0

しかし、メソッドだけが何かを返すことになっていますか? – mogli

+0

良い点は、おそらく、 – coobird

0

は、「MyClass.classは」と意味的に同じです。

主な違いは、上記のコードフラグメントがClassNotFoundExceptionをスローするが、MyClass.classがそれをスローできるとは思わない(ClassDefNotFoundErrorがスローされる可能性がありますが、それはより一般的な問題です)。また、MyClass.classはimport文で動作しますが、Class.forname()では完全修飾クラス名を渡す必要があります。


私が思い出したように、MyClass.classはMyClassを初期化しないので、静的初期化子は呼び出されません。

+0

本当ですか? MyClass.classを使用するcozはMyClassの静的ブロックを実行しませんが、Class.forName( "MyClass")を使用します。それでは、どのようにして両者を同義的に一致させることができますか? – mogli

+0

良い点、ありがとう。私はそれに応じて私の答えを修正しました。 – skaffman

+0

Class.forName(className)はClass.forName(className、true、loader)を呼び出すため、静的初期化コードを実行します。真部分はクラスの初期化を指定します – Jorn

0

右のように、「クラス」インスタンス変数はありません。実際にはすべてのクラスに存在します。 MyClass.classはMyClassのClassインスタンスを直接取得します。あなたが反射にどれほど身近なのかよく分かりませんが、これで作業を開始できます。このチュートリアルでは、できることのいくつかの例を確認することができます。 http://www.ibm.com/developerworks/library/j-dyn0603/

Reflectionを使用すると、プログラムは実行時に独自の動作を表示および変更できます。そのタイプの "メタプログラミング"。"

+0

私は反射を知っていますが、私は多くのことについてよく分かりません class literalの詳細。 – mogli

関連する問題