2011-07-25 14 views
11

Mój zespół jest w trakcie czyszczenia naszego korzystania z throws Exception i usuwania lub zastępowania ich z określonymi wyjątkami.Czy warto używać generycznych wyjątków?

Powszechne rzuty są spowodowane tym, że nie znaleziono obiektu. Czy powinniśmy rzucać generyczne NotFoundException lub specyficzne SomeClassNotFoundException dla każdej klasy encji?

Jeśli powinniśmy rzucić wyjątek, czy powinniśmy tworzyć konkretną klasę wyjątków dla każdego typu jednostki? Czy możemy bezpiecznie używać leków generycznych? Podoba Ci się to class NotFoundException<T extends EntityBaseClass> extends Exception, a następnie konstruktor zadeklaruje, z jakim typem encji mamy do czynienia?

Jeśli powinniśmy rzucić wyjątek i nie używać generycznych, czy te wyjątki powinny rozszerzać lub wdrażać klasę abstrakcyjną lub interfejs abstrakcji NotFoundException?

Odpowiedz

11

Prostym testem na pytanie

powinniśmy być tworząc specyficzną klasę wyjątku dla każdego typu jednostki?

jest

Czy istnieją okoliczności, w których musielibyśmy napisać catch klauzulę, która będzie złapać „nie znaleziono” wyjątek rzucony przez jakiegoś klasy X a nie przez inne klasy?

Jeśli odpowiedź brzmi "tak", to gwarantowany jest oddzielny ClassXNotFoundException; w przeciwnym razie prawdopodobnie tak nie jest.

Jeśli chodzi o drugą połowę pytania, język nie zezwala na użycie generycznych typów wyjątków.

20

To nie wolno robić wyjątków rodzajowy - nie będzie kompilować (JLS §8.1.2):

Jest to błąd kompilacji, jeśli ogólna klasa jest bezpośrednim lub pośrednim podklasa Throwable

Ponieważ parametry typów generycznych są usuwane w czasie wykonywania, nie ma możliwości odróżnienia ogólnych wyjątków o różnych parametrach typów w klauzuli catch, dlatego ogólne wyjątki nie są obsługiwane. Tak naprawdę nie masz wyboru, jeśli chodzi o używanie ogólnych wyjątków.

5

Czy powinniśmy tworzyć konkretną klasę Exception dla każdego typu jednostki?

Jeśli osoby dzwoniące z Twojego kodu mogą w uzasadniony sposób odzyskać dane po nieodnalezieniu definicji jednostki i skorzystają na możliwości przyjęcia innej strategii odzyskiwania na typ jednostki, to tak. W przeciwnym razie nie.

Czy możemy bezpiecznie używać leków generycznych? Podobnie jak ta klasa NotFoundException rozszerza wyjątek, a następnie konstruktor dba o zadeklarowanie typu obiektu, z którym mamy do czynienia?

To nie pomoże dzwoniącym twojego kodu zmienić typu jednostki związanej z awarią.

Nawet jeśli zdefiniować typ wyjątku MyParameterizedException<T> następnie z powodu typu skasowaniem, rozmówca nie może zrobić

try { 
    callYourCode(); 
} catch (MyParameterizedException<TypeA> ex) { 
    // some handling code 
} catch (MyParameterizedException<TypeB> ex) { 
    // some different handling code for type b 
} 

bo z typu skasowaniem wygląda

try { 
    callYourCode(); 
} catch (MyParameterizedException ex) { 
    // some handling code 
} catch (MyParameterizedException ex) { 
    // some different handling code for type b 
} 

i drugiego bloku catch gdyby tworzyły być nieosiągalnym kodem, a więc zostanie on odrzucony podczas kompilacji przez javac. Pierwszy blok catch zostałby wprowadzony dla typu b i wpisz jednostki (i wszelkie inne typy również).

Jeśli powinniśmy rzucać konkretny wyjątek, a nie przy użyciu rodzajowych, należy te wyjątki rozszerzyć lub wdrożyć NotFoundException abstrakcyjne klasy lub interfejsu?

Jeśli osoby dzwoniące z twojego kodu byłyby zaskoczone, gdyby nie, to tak.

Jeśli osoby korzystające z twojego kodu odniosłyby korzyść z powodu awarii jednostek obsługiwanych przez kod obsługujący inne NotFoundException s, to tak.

Jeśli osoby wywołujące Twój kod prawdopodobnie nie będą chciały mieć błędów lokalizowania definicji typu jednostki w taki sam sposób, jak w innych warunkach NotFound, to nie.

0

Myślę, że wszyscy odpowiadają, że nie potrzebujesz konkretnego wyjątku. Sprawdzałem, jak Hibernuj definiuje nie znaleziony wyjątek. Znalazłem EntityNotFoundException Dodam, że NIE powinieneś nawet tworzyć własnego wyjątku, po prostu użyj go ponownie. Rozszerza to wyjątek RuntimeException, co oznacza, że ​​nie zmuszasz ludzi do przechwytywania. Ale jeśli chcesz, możesz ponownie użyć istniejącej klasy w J2EE. Co jest zawsze lepsze niż pisanie nowego kodu.

5

Zamiast:

public Class EntityNotFoundException<T extends EntityBaseClass> extends Exception { 

} 

Należy użyć:

public Class EntityNotFoundException extends Exception { 
    private Class<? extends EntityBaseClass> clazz; 

    public EntityNotFoundException(Class<? extends EntityBaseClass> clazz) { 
     this.clazz = clazz; 
    } 

    . . . 
} 

W ten sposób można zachować odniesienie do typu jednostki, która generuje wyjątek. Aby rzucić jedną z tych wyjątków można użyć:

throw new EntityNotFoundException(Customer.class); 

Kompilator będzie potwierdzić, że klient nie rozciąga EntityBaseClass.

+0

Należy zauważyć, że EntityNotFoundException jest zduplikowaną nazwą dla javax.persistance.EntityNotFoundException. –

Powiązane problemy