2013-08-08 10 views
6

Dlaczego Java często wyrzuca wyjątek wskaźnika pustego, gdy próbuję uzyskać dostęp do wartości null, a Cel C nie?Java vs Cel C w przypadku wyjątku nullpointer

Java:

public class SubscribeEmailActivity { 
    String status; 

    public static void main(String[] args){ 

     if(Status.equals(null)||status.equals(""){ 

      // i am getting error here 

     } 
    } 

} 

Cel C:

//in .h file 
NSString *exp; 

//in .m file 
if ([exp isEqualToString:NULL] ||[exp isEqualToString:@""]) 
{ 
    // i am not getting any error 
} 
+9

Ponieważ są to różne języki? Nie ma żadnej bezwzględnej reguły określającej, w jaki sposób język musi obsługiwać metody wywoływania na 'null'. To decyzja twórców języka stworzona z różnych powodów. – DrummerB

+0

Mam tę samą wątpliwość – ArunMak

+4

Nie wiem Objective-c, ale [exp isEqualToString: NULL] nie brzmi dla mnie jak sprawdzanie zerowej wartości, ale raczej sprawdzanie "NULL" i sprawdzanie zerowej wartości Java nie ma sensu . –

Odpowiedz

6

Ostatecznie, jedynym sposobem, aby całkowicie rozwiązać tego problemu jest użycie innego języka programowania:

  • w Objective-C, można zrobić równowartość wywoływać metodę na zero, i absolutnie nic się nie stanie . To sprawia, że ​​większość kontroli zerowych jest niepotrzebna, ale może sprawić, że błędy będą trudniejsze do zdiagnozowania.
  • W języku Nice, w języku pochodnym Java, istnieją dwie wersje wszystkich typów: wersja potencjalnie pusta i wersja niezerowa. Możesz wywoływać metody tylko na typach nie-pustych. Potencjalnie-null typy mogą być konwertowane na typy bez wartości null poprzez jawne sprawdzanie wartości NULL. Dzięki temu łatwiej jest wiedzieć, gdzie wymagane są kontrole null, a gdzie nie.
7

Problem jest w swojej oceny w języku Java, powinno być:

if(status == null||status.equals("")) { 
    //Do not try to dereference status.... 

Należy zauważyć, że to tylko działa, ponieważ Java i inne języki pozwalają na skróty w ocenach logicznych. Niektóre proste Boole'a w tym przypadku:

true || ??? => true 

Po pierwszej kadencji wartość true, wiemy, że albo warunkowego będzie również oceniać true, nie ma potrzeby, aby zbadać drugą kadencję.

Dodatkowo można użyć Apache Commons isEmpty() lub rolki własne:

public static final boolean isEmpty(String arg0) { 
    if(arg0 == null) return true; 
    if(arg0.trim().length() < 1) return true; 
    return false; 
} 

Wersja pokazana jest zbliżona do isBlank w Apache Commons.

+0

status.equals ("") można również zapisać jako status.isEmpty() – Carnal

+0

W rzeczywistości można uniknąć obu połączeń, wywołując "" ".equals (status)'. W ten sposób metoda '.equals()' będzie * nigdy * wywoływana na obiekcie zerowym, a jednocześnie będziesz testował, czy łańcuch znaków jest pusty, gdy "status" nie ma wartości null. – tomacco

2

Jeśli zmienna status jest null w języku Java, próba wywołania status.equals() spowoduje zgłoszenie wyjątku NullPointer. isEqualToString nie jest funkcją członkowską łańcuchów Objective-C, po prostu porównuje łańcuch i obiekt.

+1

isEqualToString: (dwukropek jest ważny) to metoda klasy NSString. – Fred

4

To prawdopodobnie nie odpowie na to pytanie, ale jedna zasada, aby uniknąć wyjątku null pointer, a jednocześnie uniknąć null czek, to aby odwrócić zaznaczenie takiego:

Status status = null; 
if("".equals(status)){ 
    //.... 
} 

które zwróci false.

podczas używania:

if(status.equals("")){ 
} 

rzuci wyjątek NPE.

+0

+1 za naprawdę wyjaśnienie różnicy – Carnal

2

To tylko kwestia sposobu zaprojektowania języka. Możesz odszukać here, jeśli jesteś wystarczająco odważny, aby zobaczyć, jak działa objc_msgSend i dlaczego możesz wysyłać wiadomości do zerowych obiektów.

4

Wywołania metody Object C są uznawane za równoważne z wysyłaniem wiadomości, a wysłanie wiadomości do nil nic nie robi. Oznacza to, że nie trzeba pisać zerowych kontroli, które byłyby wymagane w Javie, co jest wygodniejsze dla programistów, którzy mogą napisać bardziej zwarty kod.

Z drugiej strony może to również być źródłem błędu: jeśli spodziewałeś się wysłać wiadomość do prawdziwego obiektu, ale zamiast tego wysłać ją do nil, w Celu C nie otrzymasz ostrzeżenia. W Javie ta operacja powoduje wygenerowanie NullPointerException, dzięki czemu staje się jasne, że masz błąd.

Ponieważ projektanci języków muszą dokonać kompromisu między wygodą a bezpieczeństwem, żadna opcja nie jest obiektywnie lepsza. Projektanci Celu C zdecydowali, że lepiej jest zaimplementować nil jako czarną dziurę: połyka wszystko, co w nią rzucacie. Projektanci Javy zdecydowali, że lepiej jest, jeśli mamy do czynienia z null wygenerowanym wyraźnym błędem. Nic więcej naprawdę.

2

W kodzie

if(Status.equals(null)||status.equals("") porównujesz String do null (null nie jest String).

Nie można porównywać łańcucha z łańcuchem innym niż ciąg. W przypadku iOS kodowania wierzę, że

[exp isEqualToString:NULL]

konwertuje argument niczego jako null lub nil są takie same, a następnie porównać je więc to działa.

Powiązane problemy