JAVA類型信息——Class對象


            JAVA類型信息——Class對象

一、RTTI概要

    1、類型信息RTTI :即對象和類的信息,例如類的名字、繼承的基類、實現的接口等。

2、類型信息的作用:程序員可以在程序運行時發現和使用類型信息。

3RTTI真正含義:運行時,識別一個對象的類型。

    4、如何在程序運行時識別對象和類的信息?

        1)傳統RTTI:即在編譯時已知道了所有的類型。

        2)反射機制:在程序運行時發現和使用類的信息。

    5RTTI的使用

import java.util.*;      //List支持泛型

//import java.awt.List;  不支持泛型

import java.util.Arrays;

abstract class Shapes{

  void draw() {System.out.println(this + ".draw()");}

  abstract public String toString();

}

class Circle extends Shapes{

  public String toString() {return "Circle";}

}

class Triangle extends Shapes{

  public String toString() {return "Triangle";}

}

class Square extends Shapes{

  public String toString() {return "Square";}

}

class Test{

  public static List<Shapes> getList(){

List<Shapes> list_aShapes = Arrays.asList(new Circle() , new Square(), new Triangle());

         return list_aShapes;

  }

}

public class Shape {

  public static void main(String[] args) {

          List<Shapes> list_aShapes = Test.getList();

          for(Shapes ob_aShapes : list_aShapes) {

                 ob_aShapes.draw();

          }

  }

}

      運行結果:Circle.draw()

Square.draw()

 Triangle.draw()

      結果分析:(1toString()都繼承Object類的toSting(),派生類的toString()都會覆蓋基類的該方法。

               2Shapes.draw()中的this間接調用toString()

               3)假設Test類是服務器端提供給客戶端使用的一個類,客戶端調用該類的方法(這里main()調用)獲得一個泛化引用,顯然,客戶端並不知道泛化引用中的確切類型,而程序員需要使用到某一個確切類型對象,這時,我們就需要到RTTI。在上面的例子中,我們只是打印出泛化引用的所有類型。

 

二、Class對象

Class對象概述

(1)持有RTTI信息

(2)每個類都有一個Class對象,每當編譯一個新類就產生一個Class對象。

(3) Class引用總是指向某個Class對象。Class引用表示的就是它所指向的對象的確切類型,而該對象便是Class類的一個對象。

()

forName()

(1)    獲取Class對象的一個引用,但引用的類還沒有加載(該類的第一個對象沒有生成)就加載了這個類.

(2)    為了產生Class引用,forName()立即就進行了初始化。

Object-getClass()

獲取Class對象的一個引用,返回表示該對象的實際類型的Class引用。

getName()

獲取全限定的類名(包括包名),即類的完整名字。

getSimpleName()

獲取類名(不包括包名)

getCanonicalName()

獲取全限定的類名(包括包名)

isInterface()

判斷Class對象是否是表示一個接口

getInterface()

返回Class對象,表示Class對象所引用的類所實現的所有接口。

getSupercalss()

返回Class對象,表示Class對象所引用的類所繼承的直接基類。應用該方法可在運行時發現一個對象完整的繼承結構。

newInstance()

返回一個Oject對象,是實現“虛擬構造器”的一種途徑。

“虛擬構造器”:我不知道你的確切的類型,但無論如何都要正確創建你自己。

使用該方法創建的類,必須帶有默認的構造器。

cast()

接受一個對象為參數,並將其轉型為Class引用的類型。該法一般是在無法使用普通轉型的情況下使用。

getClassLoader()

返回該類的類加載器。

getComponentType()

返回表示數組組件類型的Class

isArray()

判定此 Class 對象是否表示一個數組類。

 

類字面常量

(1)一種用來生成對Class對象引用的方法。

(2)相對forName()而言,效率更高,而且不會立即引發初始化。

(3)方法:className.class;

(4)既可用於普通類,也可用於接口、數組、基本數據類型。

 

                  …………等價於…………

 

                  boolean.class

Boolean.class      

 

char.class

Char.class

 

byte.class

Byte.class

 

short.class

Short.class

 

int.class

Integer.class

 

long.class

Long.class

 

float.class

Float.class

 

double.class

Double.class

 

void.class

Void.class

 

 

 

 

泛化的Class引用

(1)實現方法:使用通配符“?”。

(2)Class<?>優於Class,即便他們是等價的。

(3)Class<?>的好處是明確地告訴編譯器你選擇了非具體的類版本,而不是由於碰巧或者疏忽而使用了一個非具體的類引用。

(4)創建一個范圍:創建一個Class引用 ,使它被限定為某種類型<className>;或該類型的任何子類型,< ? extends superClass>;或者該類型的超類,< ? super super sunClassName>

 

 

 

 

 

 

 

 

 

import java.lang.Class;

import java.lang.reflect.Constructor;

interface Iterface1{}

interface Iterface2{}

abstract class SuperClass{

     SuperClass(){};

     SuperClass(int i){}

     static {System.out.println("creating SuperClass");}

}

class SunClass extends SuperClass implements  Iterface1, Iterface2{

     SunClass(){super(1);}

     static {System.out.println("creating SunClass");}

}

class SunClass1 extends SuperClass implements  Iterface1, Iterface2{

     SunClass1(){super(1);}

     static {System.out.println("creating SunClass1");}

}

public class ClassObject {

    static void printInfo(Class cc) {

         System.out.println("Class name:" + cc.getName()

                       + "      is Interface : " + cc.isInterface()

                       +"       Simple name : " + cc.getSimpleName()

                       + "      Canonical name : " + cc.getCanonicalName());

    }

     public static void main(String[] args) {

            System.out.println("/////forName()與類字面常量////////");

            Class ob_aClass = null;

             //對類的引用不引發初始化

            Class ob_cClass = SuperClass.class;                

            System.out.println("After creating SuperClass");

            try {

                   //立即初始化類

                    ob_aClass = Class.forName("rtti.SunClass");  

                    System.out.println("After creating SunClass");

                    System.out.println("///////////////////////////////////");

            }catch(ClassNotFoundException e){

                   System.out.println("Can't find SunClass.");

                   System.exit(1);

            }

            printInfo(ob_aClass);

            System.out.println("///////Class引用實現的接口///////");

            for(Class face : ob_aClass.getInterfaces())

                   printInfo(face);

            System.out.println("//////Class引用的基類////////");

            Class ob_bClass = ob_aClass.getSuperclass();

            printInfo(ob_bClass);

            System.out.println("///////newInstance()///////");

            Object ob_aObject = null;

            try {

                   ob_aObject = ob_aClass.newInstance();

                   //運行剖出異常   newInstance()該法必須由Class.forName()調用

                   //ob_aObject = ob_bClass.newInstance(); 

            }catch(InstantiationException e){

                   System.out.println("Can't instante.");

                   System.exit(1);

            }catch(IllegalAccessException e){

                   System.out.println("Can't access.");

                   System.exit(1);

            }

            printInfo(ob_aObject.getClass());

            System.out.println("//////Class引用的泛型////////");

            Class <? extends SuperClass>  ob_dClass = SunClass.class;

            printInfo(ob_dClass);

            Class <? extends SuperClass>  ob_eClass = SunClass1.class;

            printInfo(ob_eClass);

            //沒有類型轉換(Class<? super SunClass>),會出錯,上位知道原因?

            Class<? super SunClass>  ob_fClass = (Class<? super SunClass>)

ob_dClass.getSuperclass();

            printInfo( ob_fClass);

     }

}

運行結果:

creating SuperClass

creating SunClass

After creating SunClass

///////////////////////////////////

Class name:rtti.SunClass      is Interface : false       Simple name : SunClass      Canonical name : rtti.SunClass

///////Class引用實現的接口///////

Class name:rtti.Iterface1      is Interface : true       Simple name : Iterface1      Canonical name : rtti.Iterface1

Class name:rtti.Iterface2      is Interface : true       Simple name : Iterface2      Canonical name : rtti.Iterface2

//////Class引用的基類////////

Class name:rtti.SuperClass      is Interface : false       Simple name : SuperClass      Canonical name : rtti.SuperClass

///////newInstance()///////

Class name:rtti.SunClass      is Interface : false       Simple name : SunClass      Canonical name : rtti.SunClass

//////Class引用的泛型////////

Class name:rtti.SunClass      is Interface : false       Simple name : SunClass      Canonical name : rtti.SunClass

Class name:rtti.SunClass1      is Interface : false       Simple name : SunClass1      Canonical name : rtti.SunClass1

Class name:rtti.SuperClass      is Interface : false       Simple name : SuperClass      Canonical name : rtti.SuperClass

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM