Cara terbaik untuk "meniadakan" contoh

409

Saya berpikir jika ada cara yang lebih baik / lebih baik untuk meniadakan instanceofdi Jawa. Sebenarnya, saya melakukan sesuatu seperti:

if(!(str instanceof String)) { /* do Something */ }

Tetapi saya berpikir bahwa sintaksis "indah" untuk melakukan ini harus ada.

Adakah yang tahu kalau itu ada, dan seperti apa sintaksisnya?


EDIT: Dengan cantik, saya mungkin mengatakan sesuatu seperti ini:

if(str !instanceof String) { /* do Something */ } // compilation fails
caarlos0
sumber
24
Aku benci aturan diutamakan untuk instanceofbegitu banyak ...
Luiscubal
4
Anda selalu dapat membuat variabel, seperti boolean strIsString = str instanceof String;...
vaughandroid
yeah @ Baqueta, adalah sebuah opsi. Tapi, perbedaan apa yang bisa terjadi dalam penggunaan memori dalam satu sintaks atau lainnya?
caarlos0
2
Bagaimana itu komentar yang konstruktif?
Louth
2
Pembuat Java dapat memperkenalkan kata kunci baru: notinstanceof . Hanya dua sen saya ^^
Stephan

Jawaban:

308

Tidak, tidak ada cara yang lebih baik; milikmu kanonik.

maerics
sumber
132

Saya tidak tahu apa yang Anda bayangkan ketika Anda mengatakan "cantik", tetapi bagaimana dengan ini? Saya pribadi berpikir itu lebih buruk daripada bentuk klasik yang Anda poskan, tetapi seseorang mungkin menyukainya ...

if (str instanceof String == false) { /* ... */ }
Natix
sumber
2
Tentang logika ganda, Anda bisa menggunakan != truebukan == false: D
Jupi
Melihat ini membantu saya untuk memahami bahwa itu if(!(str instanceof String)) adalah satu-satunya cara yang benar, dan saya harus berhenti memikirkan alternatif
Vikash
Saya suka solusi ini karena saya tidak diharuskan untuk membangun tumpukan logam saat membacanya!
JaM
60

Anda dapat menggunakan Class.isInstancemetode ini:

if(!String.class.isInstance(str)) { /* do Something */ }

... tapi itu masih dinegasikan dan sangat jelek.

Dacwe
sumber
5
sedikit lebih baik, kurung kelebihan membuat kode jelek, IMHO.
caarlos0
Bukankah ini lebih lambat?
maxammann
4
Ini memiliki perilaku yang berbeda. Instanceof kata kunci termasuk subclass, metode tidak, Anda perlu menggunakan Class.isAssignableFrom untuk mereplikasi perilaku.
Chris Cooper
7
@ChrisCooper Ini tidak benar:this method returns true if the specified Object argument is an instance of the represented class (or of any of its subclasses)
Natix
24

Biasanya Anda tidak hanya menginginkan klausa iftetapi elsejuga.

if(!(str instanceof String)) { /* do Something */ } 
else { /* do something else */ }

dapat ditulis sebagai

if(str instanceof String) { /* do Something else */ } 
else { /* do something */ }

Atau Anda dapat menulis kode sehingga Anda tidak perlu tahu apakah ini String atau bukan. misalnya

if(!(str instanceof String)) { str = str.toString(); } 

dapat ditulis sebagai

str = str.toString();
Peter Lawrey
sumber
12

Jika Anda dapat menggunakan impor statis, dan kode moral Anda mengizinkannya

public class ObjectUtils {
    private final Object obj;
    private ObjectUtils(Object obj) {
        this.obj = obj;
    }

    public static ObjectUtils thisObj(Object obj){
        return new ObjectUtils(obj);
    }

    public boolean isNotA(Class<?> clazz){
        return !clazz.isInstance(obj);
    }
}

Lalu...

import static notinstanceof.ObjectUtils.*;

public class Main {

    public static void main(String[] args) {
        String a = "";
        if (thisObj(a).isNotA(String.class)) {
            System.out.println("It is not a String");
        }
        if (thisObj(a).isNotA(Integer.class)) {
            System.out.println("It is not an Integer");
        }
    }    
}

Ini hanya latihan antarmuka yang lancar, saya tidak akan pernah menggunakannya dalam kode kehidupan nyata!
Gunakan cara klasik Anda, itu tidak akan membingungkan orang lain membaca kode Anda!

Pablo Grisafi
sumber
Saya tidak suka impor statis .. toh terima kasih sudah mencoba membantu :)
caarlos0
4

Jika Anda merasa lebih dapat dimengerti, Anda dapat melakukan sesuatu seperti ini dengan Java 8:

public static final Predicate<Object> isInstanceOfTheClass = 
    objectToTest -> objectToTest instanceof TheClass;

public static final Predicate<Object> isNotInstanceOfTheClass = 
    isInstanceOfTheClass.negate(); // or objectToTest -> !(objectToTest instanceof TheClass)

if (isNotInstanceOfTheClass.test(myObject)) {
    // do something
}
Paul
sumber
1
Dengan Java 11, ini seharusnya bekerja if (Predicate.not(isInstanceOfTheClass).test(myObject)) { .... Tidak lebih baik, imo, tetapi harus bekerja!
Patrick M
3

ok hanya dua sen saya, gunakan metode string is:

public static boolean isString(Object thing) {
    return thing instanceof String;
}

public void someMethod(Object thing){
    if (!isString(thing)) {
        return null;
    }
    log.debug("my thing is valid");
}
tibi
sumber
0

Anda dapat mencapai dengan melakukan di bawah cara .. tambahkan saja kondisi dengan menambahkan braket if(!(condition with instanceOf))dengan seluruh kondisi dengan menambahkan !operator di awal seperti cara yang disebutkan dalam cuplikan kode di bawah ini.

if(!(str instanceof String)) { /* do Something */ } // COMPILATION WORK

dari pada

if(str !instanceof String) { /* do Something */ } // COMPILATION FAIL
Dharmesh Baldha
sumber
0

Saya setuju bahwa dalam kebanyakan kasus itu if (!(x instanceof Y)) {...}adalah pendekatan terbaik, tetapi dalam beberapa kasus membuat isY(x)fungsi sehingga Anda bisaif (!isY(x)) {...} bermanfaat.

Saya seorang pemula naskah, dan saya telah bertemu dengan pertanyaan S / O ini beberapa kali selama beberapa minggu terakhir, jadi bagi para googler cara mengetik naskah untuk melakukan ini adalah dengan membuat tipuan seperti ini:

typeGuards.ts

export function isHTMLInputElement (value: any): value is HTMLInputElement {
  return value instanceof HTMLInputElement
}

pemakaian

if (!isHTMLInputElement(x)) throw new RangeError()
// do something with an HTMLInputElement

Saya kira satu-satunya alasan mengapa ini mungkin sesuai dalam naskah dan bukan js biasa adalah bahwa typeguard adalah konvensi umum, jadi jika Anda menulisnya untuk antarmuka lain, masuk akal / dapat dimengerti / alami untuk menulisnya untuk kelas juga.

Ada lebih banyak detail tentang penjaga tipe yang ditentukan pengguna seperti ini di dokumen

Mr5o1
sumber