2014-06-26 65 views
1

請對以下類別看,我需要檢查,如果存在變量的有效值。所有工作正常,如果存在變量,而不是null一個合適的值,當談到null,則行爲是不是我所期望的(雖然它可能是有道理的,如果Integer a = null;時爲a instanceof Integer檢查,Java的強制類型轉換,對象類型和超載問題

可有人指導我如何從下面的類實現正確的結果?

package com.mazhar.hassan; 

public class ValueChecker { 
    public static boolean empty(Integer value) { 
     System.out.println("Integer"); 
     return (value != null && value.intValue() > 0); 
    } 
    public static boolean empty(Long value) { 
     System.out.println("Long"); 
     return (value != null && value.longValue() > 0); 
    } 
    public static boolean empty(String value) { 
     System.out.println("String"); 
     return (value != null && value.length() > 0); 
    } 
    public static boolean empty(Object value) { 
     System.out.println("Object"); 
     return (value != null); 
    } 
    public static void checkAll(Object... args) { 
     for(Object o: args) { 
      if (o instanceof Integer) { 
       empty((Integer)o); 
      } 
      else if (o instanceof Long) { 
       empty((Long)o); 
      } 
      else if (o instanceof String) { 
       empty((String)o); 
      } 
      else { 
       empty(o); 
      } 
     } 
    } 
    public static void main (String[] args) { 
     Integer a = null; 
     Long b = null; 
     String x = null; 
     Object y = null; 

     if (a instanceof Integer) { 
      System.out.println("a is Integer"); 
     } else { 
      System.out.println("a is not Integer"); 
     } 

     System.out.println("/---------------------------------------------------/"); 
     checkAll(a,b,x,y); 
     System.out.println("/---------------------------------------------------/"); 
     empty(a); 
     empty(b); 
     empty(x); 
     empty(y); 
    } 
} 

爲什麼我需要確切類型檢查,我thave扔誤差修改,如「不是有效的整數」,「無有效龍」等

以上級的輸出如下。

/-----------------------(Output 1)----------------------------/ 
a is not Integer 
/-----------------------(Output 2)----------------------------/ 
Object 
Object 
Object 
Object 
/------------------------(Output 3)---------------------------/ 
Integer 
Long 
String 
Object 

輸出1:a不是整數(通過的instanceof選中)不能識別它,但傳遞給重載函數時轉到正確的功能(輸出3)

輸出2:如何實現checkAll與多/動態PARAM checkAll(varInt,varLong,varString,varObject)

+0

我認爲你應該提出一個通用的空指針錯誤,類似「字段不能爲空」,如果有任何數據,那麼驗證具體的格式(在這種情況下,你甚至不需要的實例)。這也將避免膠水代碼(如果xxx!= null,則複製並粘貼)。讓我知道這是否符合您的需求。 –

回答

5

輸出1的行爲是由於方法過載被綁定在編譯時間造成的。所以該程序運行之前的具體超載挑必然。 instanceof,在另一方面,是一個運行時檢查。

因此,在運行時a instanceof Integer實際上是null instanceof Integer,這顯然是false

但對於每個這些單個方法調用的,適當的方法被調用,因爲編譯器結合的方法的具體過載在編譯時,基於該變量的引用類型。因此:

empty(a); // Compiled to a call to empty(Integer value) 
empty(b); // Compiled to a call to empty(Long value) 
empty(x); // Compiled to a call to empty(String value) 
empty(y); // Compiled to a call to empty(Object value) 

所以不管實際的對象,它abxy參考,您總能獲得您的控制檯上的正確輸出相應的對象。


輸出2:如何多/動態PARAM checkAll實現checkAll(varInt,varLong,varString,varObject)

好吧,如果你要通過null,你可以真的。nullnull在運行時,並沒有與之相關的任何類型的信息。該JVM不能告訴一個null是一個「String null」或「Object null」。這只是null。所以,你不能真正實現多個檢查要爲null輸入 - null instanceof ______總是會返回false,讓您隨時與您的默認情況下結束。

如果你正確地傳遞實際的對象,不過,方法應該工作。

+0

很好的解釋。 –

+1

@NetSurgeon謝謝!有趣的事實:如果你用'empty(null)'替換了任何'empty(_)',你會得到一個編譯器錯誤,因爲編譯器不能找出綁定的方法。儘管如此,無法想象這會太有幫助。 – awksp

+0

哦,是的,如果null直接傳遞了它的編譯器錯誤。非常感謝。 –

1

問題:

Integer a = null; 
    Long b = null; 
    String x = null; 
    Object y = null; 

你不能使用instanceof的空值,它希望被實例化的對象從而給你錯誤的結果。

解決方案:

instantaite您檢查例如第一前的物體。

+0

正確,這就是我從上述經驗中所理解的。但是如果您看到第三個輸出,則重載函數將識別這些空變量的類型。我需要知道他們是怎麼做到的? –

+0

這不是我(-ve) –

+0

@NetSurgeon umm因爲你在檢查之前打印它。 –

1

這裏的問題是,當你在你的循環檢查的instanceof,你正在檢查nullnull不是任何事物的一個實例,它是缺少一個實例。

如果你想實現這樣的事情,你將不得不改變你的API checkAll(Object ...)的東西,告訴函數期待什麼類型:

public class ValueChecker { 
    public static boolean checkAll(Object[] args, Class<?>[] types) { 
     if (args == null || types == null || args.length != types.length) 
      throw new RuntimeException("programming error"); 
     for (int i = 0; i < args.length; i++) { 
      if (types[i] == null) 
       throw new RuntimeException("programming error"); 
      if (args[i] == null || !types[i].isAssignableFrom(args[i].getClass())) { 
       System.out.println("arg " + (i +1) + " is not " + types[i].getSimpleName()); 
       return false; 
      } 
     } 
     return true; 
    } 

    public static void main(String[] args) { 
     Integer a = null; 
     Long b = null; 
     String x = null; 
     Object y = null; 

     checkAll(
       new Object[] {a, b, x, y}, 
       new Class<?>[] {Integer.class, Long.class, String.class, Object.class} 
     ); 
    } 
}