2009-06-23 17 views

Odpowiedz

50
public static <T> T as(Class<T> t, Object o) { 
    return t.isInstance(o) ? t.cast(o) : null; 
} 

Zastosowanie:

MyType a = as(MyType.class, new MyType()); 
// 'a' is not null 

MyType b = as(MyType.class, ""); 
// b is null 
+0

@erickson: To jest idealne! +10 gdybym mógł (wiedziałem, że generyczny mógłby być tutaj użyty: P) Dodałem przykładowe użycie, jeśli chcesz, możesz wycofać. – OscarRyz

+0

+1 za bezpieczeństwo podczas kompilacji – dfa

+0

Dzięki Oscar, bardzo ładnie! – erickson

27

Można użyć słowa kluczowego instanceof, aby określić, czy można poprawnie rzutować.

return obj instanceof String?(String)obj: null; 

Oczywiście może być generowany i wprowadzany do funkcji, ale myślę, że pytanie dotyczyło tego, co oznacza, że ​​Java musi to osiągnąć.

+1

Nie jestem pewien, czy tego chce Shoosh. Prawdopodobnie potrzebny jest bardziej ogólny sposób traktowania obsady. Byłaby to idealna odpowiedź dla "Jak zweryfikowałem mój obiekt jest instancją danej klasy" :) :) – OscarRyz

+0

Potrzebuję "innej" klauzuli ... –

+1

Myślę, że nie jesteśmy tutaj, aby rozwiązywać problemy dla innych, ale dostarczać wskazówek . Wskazanie właściwego kierunku powinno wystarczyć. –

0

AFAIK, byłoby to (jeden) ze sposobów, aby to zrobić:

SomeClassToCastTo object = null; 
try { 
    SomeClassToCastTo object = SomeClassToCastTo.class.cast(anotherObject); 
} 
catch (ClassCastException e) { 
    object = null; 
} 

brzydki, ale powinien robić to, co chcesz ...

+0

To nie jest dobry przypadek użycia refleksyjnej metody "cast()". Zobacz http://stackoverflow.com/questions/243811/when-should-i-use-the-java-5-method-cast-of-class, aby uzyskać więcej informacji. – erickson

+0

Zgadzam się, miałem bart mózgowy i zapomniałem o operatorze 'instanceof'. – Peter

+1

tworzenie wyjątku w tym przypadku można byłoby uniknąć. wyjątki są obiektami, więc dobrze jest nie tworzyć ich niepotrzebnie. – cd1

0

W Javie jeśli obsada nie będziesz uzyskać wyjątek ClassCastException. Możesz przechwycić wyjątek i ustawić obiekt docelowy na wartość null.

-1

można obsługiwać ten połowu ClassCastException

+2

Za każdym razem, gdy wyjątek zostanie rzucony, wiąże się to z dużym obciążeniem. Właśnie dlatego Wyjątki powinny być właśnie tym - "wyjątkiem". Obsługa wyjątków powinna być zarezerwowana dla wydarzeń naprawdę wyjątkowych. Gdy wyjątki stają się regułą, programujesz źle. O wiele lepiej jest używać sprawdzania typu. – StriplingWarrior

0

Można też złapać wyjątek:

Foo f = null; 
try { 
    f = Foo(bar); 
} 
catch (ClassCastException e) {} 

lub sprawdzić typ:

Foo f = null; 
if (bar instanceof Foo) 
    f = (Foo)bar; 
+3

Puste bloki blokujące są bardzo złym nawykiem ... faktycznie, myślę, że kompilator powinien uderzyć Cię w twarz, kiedy to zrobisz;). W każdym razie, nigdy nie powinieneś polegać na wyjątkach dla czegoś, co możesz sprawdzić bez wyrzucania wyjątku. –

+2

Dlatego właśnie podałem wersję bez wyjątku. – Pesto

5

Można, ale nie z jednej funkcji w Java:

public B nullCast(Object a) { 

    if (a instanceof B) { 
    return (B) a; 
    } else { 
    return null; 
    } 
} 

EDIT: Należy pamiętać, że nie można dokonać klasa B generic (dla tego przykładu) bez dodawania klasę docelową (ma to związek z faktem, że typ rodzajowy nie jest dostępny do instanceof):

public <V, T extends V> T cast(V obj, Class<T> cls) { 
    if (cls.isInstance(obj)) { 
    return cls.cast(obj); 
    } else { 
    return null; 
    } 
} 
+0

Tak, ale podawałem ogólny pomysł, a nie konkretną metodę. –

+0

C# 's 'as' działa na obiektach pustych. – Nyerguds

2
MyType e = (MyType) orNull(object, MyType.class); 
// if "object" is not an instanceof MyType, then e will be null. 

...

public static Object orNull(Object o , Class type) { 
    return type.isIntance(o) ? o : null; 
} 

myślę, może to jakoś zrobić z rodzajowych również, ale myślę, ale prawdopodobnie nie jest to, co jest potrzebne.

Ta prosta metoda otrzymuje obiekt i zwraca obiekt, ponieważ rzutowanie odbywa się w kliencie metody.

0

Oba roztwory powyżej są nieco niewygodne:

odlewnicze i uchwyt ClassCastException: tworzenie obiektu wyjątku może być kosztowne (na przykład obliczenia śledzenia stosu).

Opisana wcześniej metoda nullCast oznacza, że ​​do każdej obsady, którą chcesz wykonać, potrzebujesz metody rzutowania.

Generics zawodzi z powodu "usunięcia typu" ...

Można utworzyć statyczną metodę pomocnika, który jest gwarantowany powrót instancją klasy docelowej lub null, a następnie rzucić wynik bez obawy wyjątek:

public static Object nullCast(Object source, Class target) { 
    if (target.isAssignableFrom(source.getClass())) { 
     return target.cast(source); 
    } else { 
     return null; 
    } 
} 

wezwanie Próbka:

Foo fooInstance = (Foo) nullCast(barInstance, Foo.class); 
Powiązane problemy