2013-02-15 3 views
0

Я намерен сделать общую динамическую функцию проверки нуля на любом объекте, прежде чем выполнять над ней какую-либо работу.Dynamic null check

Например:

Class A{ 
B b; 

// with getters and setters of b 
} 

class B{ 
C c; 
//with getters and setters of c 
} 

class C{ 

    BigInteger d; 

//with getters and setters of d 
} 

теперь, я хочу, чтобы проверить ли objA.getB().getC().getD() возвращает какое-то значение или бросает NullPointerException?

По общим Я имею в виду, я могу передать объект любого типа к нему, что-то вроде ниже функции

CheckNull.checkingDynamicNull("objA.getB().getC().getD()") 

возвратит меня истинным или ложным в зависимости от случая.

Любые идеи?

+0

'objA.getB() .getC(). getD() == null' –

+1

@GrijeshChauhan .. А что, если 'getB()' возвратил 'null'? –

+0

Это то, что я хочу обработать, возвращая false через эту функцию .... – advaita

ответ

0

Что об этом:

public boolean checkingDynamicNull(A objA) { 
    try { 
     objA.getB().getC().getD().toString(); 
    } catch(NullPointerException npe) { 
     return true; 
    } 
    return false; 
} 
+0

перед вызовом 'getB()' cast' objA' '' A'. – Azodious

+0

Я думал об этом, но это не будет общей функцией .... не так ли? ... – advaita

+0

Правда, но я не вижу смысла использовать этот метод для общего Util. Вы должны обрабатывать 'null' в специальном случае. Этот метод не обрабатывает 'null' изящно. – oliholz

0

Чтобы знать, если оператор будет возвращать null, вы должны выполнить ее первой. Даже если вам удастся выполнить оператор, указанный в String, вашему методу, это ничем не отличается от его запуска и проверки того, является ли результат null или поймать NullPointerException.

+0

AFAIK мы можем атаковать проблему с помощью методов отражения .... но у меня нет никаких рук ... – advaita

1

К сожалению, невозможно передать funktion в метод на Java (но Java 8 будет). Кроме того, если вы передадите имя переменной как String, это не будет работать, поскольку метод получения не имеет возможности узнать, какой объект сопоставляется с этой переменной (если вы игнорируете отражение, но даже с тем, что вы ввернуты, если это локальная переменная).

Другим способом было бы сделать что-то вроде этого

boolean nullCheck(Object obj, String Methods) 

, а затем разобрать строку на методы и вызывать их на объекте. Но это не сработает, если у вас есть методы с аргументами.

Короче говоря: Это больше хлопот, то это стоит

В большинстве случаев вы хотите иметь что-то вроде этого

if(object == null){ 
    //error behavior 
} 

Это предполагает, что вы хотите бросить определенное исключение, есть средства, чтобы получить значение для нулевого объекта elswhere или хотите что-то сделать, прежде чем вы выбросите исключение. Если вы просто хотите выбросить исключение (то есть не NullPointerException)

assert object != null 
+1

+1 для «Короче: это больше проблем, чем стоит» – KidTempo

+0

это, вероятно, решит мою проблему, поскольку я не намерены передавать какие-либо аргументы в методах, поскольку в основном они являются нормальными геттерами. – advaita

0

С отражением это может быть что-то вроде этого:

nullCheck(objA, "getB", "getC", "getD"); 

public static boolean nullCheck(Object obj, String... methods) { 
    Object o = obj; 
    Class<?> clazz = obj.getClass(); 
    Method method = null; 
    try { 
     for(String name : methods) { 
      method = clazz.getMethod(name, null); 
      o = method.invoke(o, null); 
      clazz = method.getReturnType(); 
     } 
    } catch(NullPointerException e) { 
     System.err.println(clazz.getSimpleName()+"(null)."+method.getName()); 
     return false; 
    } catch(NoSuchMethodException e) { 
     e.printStackTrace(); 
    } catch(SecurityException e) { 
     e.printStackTrace(); 
    } catch(IllegalAccessException e) { 
     e.printStackTrace(); 
    } catch(IllegalArgumentException e) { 
     e.printStackTrace(); 
    } catch(InvocationTargetException e) { 
     e.printStackTrace(); 
    } 
    return true; 
} 

System.out.println(nullCheck(GraphicsEnvironment.getLocalGraphicsEnvironment(), "getDefaultScreenDevice", "getDisplayMode", "toString")); 
System.out.println(nullCheck(GraphicsEnvironment.getLocalGraphicsEnvironment(), "getDefaultScreenDevice", "getFullScreenWindow", "doLayout")); 

приносит

true 
false 

'Window(null).doLayout' 
0

вы можете добиться этого с помощью отражения, вот ваш метод:

public boolean dynamicNullCheck(Object o, String path) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException { 
    Object object= o; 
    for (String element : path.split("\\.")) 
    { 
     Field field = object.getClass().getDeclaredField(element); 
     field.setAccessible(true); 
     Object fieldVal = field.get(object); 

     if (fieldVal!=null) 
     { 
      field.setAccessible(true); 
      object = fieldVal; 
     } 
     else 
     { 
      return true; 
     } 


    } 
    return false; 


} 

использовать его, давая корневой элемент и путь к каждому объекту, т.е. dynamicNullCheck(objA,"b.c.d")