1. 程式人生 > >Java中物件的型別判斷

Java中物件的型別判斷

instanceof

判斷一個物件是否是一個類的例項,用Java中自帶的關鍵字instanceof似乎可以做到(僅從關鍵字名稱上可以猜測出),如下面的程式碼:

public static void main(String args[]) {
    Object i = new Integer(7);
    if (i instanceof Number) {
        System.out.println("Integer i is a Number");
    } else {
        System.out.println("Integer i isn't a Number"
); } if (i instanceof Serializable) { System.out.println("Integer i is a Serializable"); } else { System.out.println("Integer i isn't a Serializable"); } if (i instanceof Integer) { System.out.println("Integer i is an Integer"); } else { System.out.println("Integer i isn't an Integer"
); } if (i instanceof Float) { System.out.println("Integer i is a Float"); } else { System.out.println("Integer i isn't a Float"); } }

類定義部分為:

public abstract class Number implements java.io.Serializable {}
public final class Integer extends Number implements Comparable
<Integer> {
}

執行結果:

Console Output :
Integer i is a Number
Integer i is a Serializable
Integer i is an Integer
Integer i isn’t a Float

然而好像和預期的不太一樣,能看出,使用該關鍵字不僅可以判斷物件是否是某個類的例項,甚至連該類繼承的基類和實現的介面也都能夠被識別為true,雖然這樣在邏輯上沒有任何問題,是可以把Integer當做一個Number來看來用,也當做一個Serializable來看來用,但是這樣返回的結果就沒有針對性了,太過於模糊,我們如果僅僅需要i instanceof Integer為true該怎麼做呢?

Class.equals

還好在Java有一個叫做Class的類,這是一個用來描述類資訊的類,我們如果要精確判斷一個物件是否是具體的一個類的例項,可以這麼做:

public static void main(String args[]) {
    Object i = new Integer(7);
    if (i.getClass().equals(Number.class)) {
        System.out.println("Integer i is a Number");
    } else {
        System.out.println("Integer i isn't a Number");
    }

    if (i.getClass().equals(Serializable.class)) {
        System.out.println("Integer i is a Serializable");
    } else {
        System.out.println("Integer i isn't a Serializable");
    }

    if (i.getClass().equals(Integer.class)) {
        System.out.println("Integer i is an Integer");
    } else {
        System.out.println("Integer i isn't an Integer");
    }

    if (i.getClass().equals(Float.class)) {
        System.out.println("Integer i is a Float");
    } else {
        System.out.println("Integer i isn't a Float");
    }
}

執行結果:

Console Output :
Integer i isn’t a Number
Integer i isn’t a Serializable
Integer i is an Integer
Integer i isn’t a Float

這樣就能達到我們的目的了,從equals函式上就可以看出,上述程式碼是比較兩個類的類資訊是否一致,全相等,這其中不考慮繼承實現的關係,當且僅當該物件是要比較的那個類的例項才返回true。

但是我們檢視原始碼的時候可以發現,其equals函式用的就是Object中的方法,沒有重寫:

public boolean equals(Object obj) {
     return (this == obj);
}

這就很奇怪了,如果是隻有比較兩個Class例項化物件的引用是否是指向同一個物件的話,這樣返回的是true,也就是說,i.getClass()Integer.class獲取到的是同一個物件?!

可是這就是事實:

無論我們用Integer例項化多少個物件,當我們呼叫getClass()方法時返回的總是同一個物件,還有Integer.class返回的也是它。
所以上面的i.getClass().equals(Number.class)改寫為i.getClass == Number.class也是成立的。
事實上每個類都會有且只有一個對應Class的物件,我們正是用這個Class物件來例項化該類的所有物件的,也就是Class中的newInstance()方法。

其實也可以理解,既然是同一個類的資訊,無論有多少個物件,他們的類資訊也都是一樣的,所以也就沒有必要例項化那麼多Class物件來存放

PS:a instanceof b的結果和b.class.isInstance(a)的結果是一致的,可以實現相同的功能,完全等價。

更加全面的型別資訊

這樣看起來就好很多了,可是我們如果想獲取更多有關於物件i的型別資訊呢?比如獲取它的基類呢?
同樣還是使用Class的物件,它裡面提供了很多方法如:

獲取父類的型別資訊:getSuperclass()
獲取實現的介面的型別資訊:getInterfaces()
獲取型別名稱:getName()、getSimpleName()、getCanonicalName()

相關推薦

java物件型別轉換

      在java開發中我們經常見到的為了降低程式間的耦合度,在定義某些類是通常使用的都是父型別,之後程式呼叫者就可以根據自己的需求將子型別賦值上去,實現功能上的呼叫,在這過程中就是運用了物件的向上轉型,執行時通過後期繫結來實現對實際子類的呼叫。這樣就實現了傳說中java的多型功能。然而有些時候為了完成某

Java物件型別判斷

instanceof 判斷一個物件是否是一個類的例項,用Java中自帶的關鍵字instanceof似乎可以做到(僅從關鍵字名稱上可以猜測出),如下面的程式碼: public static void main(String args[]) { Obje

java 集合物件型別(個人見解)

先貼出面試題 以下程式碼執行結果是什麼。 public class Test { public static void main(String args[]) { List Listlist1 = new ArrayList();

JAVA型別物件(Integer和Int)

Integer是物件 Int是型別 比如 boolean 和Boolean就也不一樣,long和Long等等 作為引數傳遞時要注意 要進行轉換如下 int到Integer: int a=3; Integer A=new Integer(a); 或: Integer A

Java如何高效判斷數組是否包含某個元素

clas AC ray 而且 一個 nan 使用 一個數 component 如何檢查一個數組(無序)是否包含一個特定的值?這是一個在Java中經常用到的並且非常有用的操作。同時,這個問題在Stack Overflow中也是一個非常熱門的問題。在投票比較高的幾個答案中給出了

java物件物件引用的區別

1.何謂物件?   在Java中有一句比較流行的話,叫做“萬物皆物件”,這是Java語言設計之初的理念之一。要理解什麼是物件,需要跟類一起結合起來理解。下面這段話引自《Java程式設計思想》中的一段原話:   “按照通俗的說法,每個物件都是某個類(class)的一個例項(instance),這裡,‘

JavaScript物件型別判斷注意點

注意點 不要使用 new Number() 、 new Boolean() 、 new String() 建立包裝物件;用 parseInt() 或 parseFloat() 來轉換任意型別到number;用

Java物件的this引用

        Java提供了一個this關鍵字,this關鍵字總是指向呼叫該方法的物件。根據this出現位置的不同,this作為物件的預設引用有兩種情形。 -構造器中引用該構造器正在初始化的物件 -在方法中引用呼叫該方法的物件   &n

Java物件的初始化過程詳解

在Java中,我們需要對物件進行初始化操作。 經常需要new 物件。但是new物件時到底發生了什麼呢? 有時候我們不是特別清晰。 所以今天又重新學習了一下JavaSE部分,又有了新的感受。 在此記錄一下 首先程式碼部分 Person類: class Person{

javadouble型別的記憶體表示

轉自[http://bbs.csdn.net/topics/260050279] 浮點數儲存的位元組格式如下: 地址 +0 +1 +2 +3 內容 SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM 這裡 S 代表符號位,1是負,0是正 E 偏移1

java資料型別

xl_echo編輯整理,交流學習請加1280023003 百戰不敗,依不自稱常勝,百敗不頹,依能奮力前行。——這才是真正的堪稱強大!! 基本資料型別有一下四種 int資料型別有: byte(8bit, -128~127) short(16bit) int

Java物件和json互相轉換的工具類

package com.Dingyu.util; import java.util.List; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaT

java物件可以存在記憶體哪些地方

注意:以下都是個人理解。如有不同之處,望提出(-_-)。 java中識別符號對應的值可以改變的叫做變數,不可以改變的叫做常量。如: //識別符號a的值可以改變,叫做變數 int a=3; a=4; //識別符號b的值不可以改變,叫做常量 final int b=3;

Java物件頭詳解

一:物件頭 HotSpot虛擬機器中,物件在記憶體中儲存的佈局可以分為三塊區域:物件頭(Header)、例項資料(Instance Data)和對齊填充(Padding)。   HotSpot虛擬機器的物件頭(Object Header)包括兩部分資訊,第一部分用於儲存物

JavaDate型別詳解

一、Date型別的初始化 1、 Date(int year, int month, int date); 直接寫入年份是得不到正確的結果的。 因為java中Date是從1900年開始算的,所以前面的第一個引數只要填入從1900年後過了多少年就是你想要得到的年份。 月需要減1,日可以直接插入。 這種方法用的比

javachar型別轉換成int型別

PlanA: char ch = '9'; if (Character.isDigit(ch)){ // 判斷是否是數字 int num = Integer.parseInt(String.valueOf(ch)); System.out.println(num); }

JAVA列舉型別結合mysql資料的使用

在我的學習過程中,我使用到了的列舉型別和資料庫配合,下面是使用過程。   public class TUser extends User implements Serializable { private static final long serialVersio

SQLServer之資料庫型別對應Java資料型別

SQL Server 型別 JDBC 型別 (java.sql.Types) Java 語言型別 bigint BIGINT long timestamp binary

JavaString型別轉換成日期型別

Java中String型別轉換成資料庫中的日期型別,新增到資料庫 //建立sdf物件,指定日期格式型別 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); //sdf將字串轉化成java.util.D

Java包裝型別與基本資料型別的異同

基本資料型別: Java語言提供了八種基本型別: 六種數字型別(四個整數型,兩個浮點型),一種字元型別,還有一種布林型。 1、整數: 包括int,short,byte,long , 初始值為0 2、浮點型: float,double , 初始值為0.0 3、字