『Thinking in Java』学習ノート-14章タイプ情報

4573 ワード

Classオブジェクト
1.新しいクラスを作成してコンパイルするたびに、クラスオブジェクトが生成されます(より適切には、同じ名前の.classファイルに保存されます).このクラスのオブジェクトを生成するために、このプログラムを実行するJava仮想マシンは「クラスローダ」と呼ばれるの各見出しページがあります.2.すべてのクラスは、最初の使用時にJVMに動的にロードされます.プログラムがクラスの静的メンバーへの最初の参照を作成すると、このクラスがロードされます.この証明コンストラクタもクラスの静的メソッドであるため、newオペレータを使用してクラスを作成する新しいオブジェクトもクラスの静的メンバーへの参照として使用されます.3.Javaプログラムは、実行を開始する前に完全にロードされていません.各部分は必要に応じてロードされます.4.Classオブジェクトは必要に応じてのみロードされ、static初期化はクラスロード時に行われます.5.いずれにしても、実行時にタイプ情報を使用するには、まず適切なClassオブジェクトへの参照を取得する必要があります.Class.forName()は、Classリファレンスを取得するためにこのタイプのオブジェクトを持つ必要がないため、この機能を実現する便利な方法です.すでに1つのタイプのオブジェクトがある場合は、getClass()メソッドを呼び出すことでClass参照を取得できます.6.getName()は、完全に限定されたクラス名を生成します.getSimpleName()は、パッケージ名を含まないクラス名を生成します.getCanonicalName()は、完全に限定されたクラス名を生成します.isInterface()メソッドは、このClassオブジェクトがインタフェースを表すかどうかを教えてくれます.getInterfaces()メソッドは、Classオブジェクトに含まれるインタフェースを表すClassオブジェクトを返します.getSuperclass()メソッドは、ベースクラスをクエリーするために使用でき、さらにクエリーするために使用されるClassオブジェクトを返します.新Instance()は、Classオブジェクトに対応するクラスを作成するために使用できますが、デフォルトのコンストラクタが必要です.
一.クラス文字定数
1.Javaではクラス文字定数「.class」の形式を使用してClassオブジェクトへの参照を生成することもできます.2.クラスの字面定数は、通常のクラスだけでなく、インタフェース、配列、および基本データ型にも適用できます.3.ClassのメソッドによるClassオブジェクトへの参照の作成とは異なり、「.class」のメソッドによる作成はこのClassオブジェクトを自動的に初期化することはなく、初期化はコンストラクタを含む静的メソッドまたは非常に数少ない静的ドメインへの最初の参照に遅延する場合に実行される.4.クラスを使用するには、(1)の3つのステップが必要である.クラス・ローダによって実行されるロード.このステップでは、バイトコードを検索し、これらのバイトコードからClassオブジェクトを作成します.(2).リンク.リンクフェーズでは、クラス内のバイトコードを検証し、静的ドメインにストレージスペースを割り当て、必要に応じて、作成した他のクラスへの参照を解析します.(3).初期化クラスにスーパークラスがある場合は、そのクラスを初期化し、静的初期化器と静的初期化ブロックを実行します.5.static final値が「コンパイル期間定数」である場合、この値はクラスを初期化する必要がなく読み込むことができます.staticドメインがfinalでない場合、アクセス時には、読み取り前にリンク(このドメインにストレージスペースを割り当てる)と初期化(ストレージスペースを初期化する)が常に要求されます.
class Initable {
    static final int staticFinal = 47;//static final      ,        
    static final int staticFinal2 = ClassInitaialization.rand.nextINt(1000);//   static final ,         ,        
    static int staticFinal3 = 47;//  final ,          
}

二.汎化Classリファレンス
1.Classリファレンスは、そのオブジェクトが指す正確なタイプを表し、そのオブジェクトはClassクラスのオブジェクトです.2.汎用構文を使用して、Class参照が指すClassオブジェクトのタイプを定義します.
public class GenericClassReference {
    public static void main(String...args) {
        Class intClass = int.class;
        Class genericIntClass = int.class;
        genericIntClass = Integer.class; // Same thing
        intClass = double.class; // Success
        //genericIntClass = double.class; // Illegal
    }
}

一般化されたClassリファレンスを使用するときに制限を緩和するには、ワイルドカードを使用します.
Class> intClass = int.class;
intClass = double.class;

3.汎用構文をClassオブジェクトに使用する場合:newInstance()は、基本的なObjectだけでなく、オブジェクトの正確なタイプを返します.
三.新しい転換文法
1.JavaSE 5にClass参照用の変換構文、すなわちcast()メソッドが追加されました.
Building b = new House();
Class houseType = House.class;
House h = houseType.cast(b); //   h = (House) b;     

タイプ変換前にチェック
1.キーワードinstanceofを使用して、オブジェクトが特定のタイプのインスタンスであるかどうかを示すブール値を返します.
if (x instanceof Dog)
    ((Dog) x).bark();

ダウンコンバートを行う前に、オブジェクトのタイプを他の情報がなければinstanceofを使用することが重要です.そうしないと、ClassCastException異常が発生します.2.instanceofには厳しい制限があります.名前付きタイプと比較するだけで、Classオブジェクトと比較することはできません.プログラムにinstanceof式がたくさん書かれている場合は、あなたの設計に欠陥がある可能性があります.
一.動的instanceof
1.isInstance()メソッドは、ネーミングタイプと比較することなく、Classオブジェクトと直接比較できます.
Pet pet = new Dog();
if (pet.isInstance(Dog.class)))
    ((Dog) pet).bark();

2.isAssignableFrom()を使用して、実行時のチェックを実行し、伝達されたオブジェクトが私たちの関心のある継承構造に属していることを確認します.
二.InstanceofとClassの等価性
1.タイプ情報を照会する際には、ClassオブジェクトをinstanceofまたはisInstance()の形式で直接比較することと重要な違いがあります.instanceofはタイプの概念を維持しており、「あなたはこのクラスですか、あるいはあなたはこのクラスの派生クラスですか?」を指しています.「==」で実際のClassオブジェクトを比較すると、継承は考慮されません.この正確なタイプ、またはそうではありません.
反射はんしゃ:実行時のクラス情報じっこうじのクラスじょうほう
1.classクラスとjava.lang.reflectクラスライブラリは、Field、MethodおよびConstructorクラス(クラスごとにMemberインタフェースが実装されています).これらのタイプのオブジェクトは、JVMによって実行時に作成された未知のクラスに対応するメンバーを表すために使用されます.2.RTTIと反射の本当の違いは、RTTIにとってコンパイラがコンパイル時に.classファイルを開いてチェックすることだけです.反射メカニズムでは.classファイルはコンパイル時に入手できないため、実行時に開くとチェックします.classファイル.
クラスメソッド抽出器
1.classのgetMethods()メソッドとgetConstructors()メソッドは、それぞれMethodオブジェクトの配列とConstructorオブジェクトの配列を返します.2.Class.forName()で生成された結果はコンパイル時には不明であるため,すべてのメソッド特徴署名情報は実行時に抽出される.反射メカニズムは、コンパイル時に完全に未知のオブジェクトを作成し、そのオブジェクトを呼び出す方法をサポートします.
インタフェースとタイプ情報
1.反射を使用することによって、パケットのアクセス権が実装されても、すべてのメソッド、さらにはprivateメソッドに到達して呼び出すことができます.メソッド名が分かれば、そのMethodオブジェクト上でsetAccessible(true)を呼び出し、invoke()メソッドで使用できます.2.finalドメインは、実際には変更に遭遇した場合に安全です.ランタイムシステムは、例外を捨てずに変更の試行を受け入れますが、実際には変更は発生しません.