Bir örneği "olumsuzlamanın" en iyi yolu


409

instanceofJava bir olumsuzlama için daha iyi / daha güzel bir yolu varsa düşünüyordum . Aslında, şöyle bir şey yapıyorum:

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

Ama bunu yapmak için "güzel" bir sözdiziminin olması gerektiğini düşünüyorum.

Var olup olmadığını ve sözdiziminin nasıl göründüğünü bilen var mı?


EDIT: Güzel, böyle bir şey söyleyebiliriz:

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

24
Öncelik kurallarından instanceofçok fazla nefret ediyorum ...
luiscubal

4
Her zaman bir değişken yaratabilirsiniz boolean strIsString = str instanceof String;...
vaughandroid

evet @ Baqueta, bir seçenektir. Ancak, bir sözdiziminde veya diğerinde bellek kullanımında ne gibi farklılıklar olabilir?
caarlos0

2
Bu nasıl yapıcı bir yorum?
Louth

2
Java içerik oluşturucuları yeni bir anahtar kelime ekleyebilir : notinstanceof . Sadece iki sent ^^
Stephan

Yanıtlar:



132

"Güzel" dediğinde ne hayal ettiğini bilmiyorum, ama buna ne dersin? Kişisel olarak, yayınladığınız klasik formdan daha kötü olduğunu düşünüyorum, ancak biri bunu beğenebilir ...

if (str instanceof String == false) { /* ... */ }

2
Çift mantık Hakkında şunu kullanabilirsiniz != trueyerine == falseD:
jupi

Bunu görmek bana if(!(str instanceof String)) bunun tek doğru yol olduğunu anlamama yardım ediyor ve alternatifleri düşünmeyi bırakmam gerekiyor
Vikash

Bu çözümü seviyorum çünkü okurken metal bir yığın oluşturmam gerekmiyor!
JaM

59

Class.isInstanceYöntemi kullanabilirsiniz :

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

... ama hala olumsuz ve oldukça çirkin.


5
biraz daha iyidir, fazla parantez kodu çirkin hale getirir IMHO.
caarlos0

Bu çok daha yavaş değil mi?
maxammann

4
Bunun farklı davranışları vardır. İnstanceof anahtar sözcüğü alt sınıfları içerir, yöntem içermez, davranışı çoğaltmak için Class.isAssignableFrom kullanmanız gerekir.
Chris Cooper

7
@ChrisCooper Bu doğru değil:this method returns true if the specified Object argument is an instance of the represented class (or of any of its subclasses)
Natix

24

Genellikle sadece ifbir elsefıkra istemezsiniz .

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

olarak yazılabilir

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

Veya kodu yazabilir, böylece onun bir String olup olmadığını bilmenize gerek yoktur. Örneğin

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

olarak yazılabilir

str = str.toString();

12

Statik içe aktarma kullanabiliyorsanız ve ahlaki kodunuz bunlara izin veriyorsa

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);
    }
}

Ve sonra...

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");
        }
    }    
}

Bu sadece akıcı bir arayüz egzersizi, bunu gerçek yaşam kodunda asla kullanmam!
Klasik tarzınızı tercih edin, kodunuzu okuyan kimsenin kafasını karıştırmaz!


Ben statik ithalat sevmiyorum .. yine de yardım etmeye çalıştığınız için teşekkürler :)
caarlos0

4

Daha anlaşılır bulursanız, Java 8 ile böyle bir şey yapabilirsiniz:

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
}

1
Java 11 ile bu işe yarayacaktır if (Predicate.not(isInstanceOfTheClass).test(myObject)) { .... Daha iyi değil, imo, ama işe yaramalı!
Patrick M

3

tamam sadece benim iki sent, bir is string yöntemi kullanın:

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");
}

0

Aşağıdaki şekilde yaparak başarabilirsiniz .. sadece başlangıçta aşağıdaki kod parçacıklarında belirtilen şekilde operatör if(!(condition with instanceOf))ekleyerek tüm koşulla parantez ekleyerek bir koşul ekleyin !.

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

onun yerine

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

0

Çoğu durumda bunun if (!(x instanceof Y)) {...}en iyi yaklaşım olduğuna katılıyorum , ancak bazı durumlarda isY(x)yapabilmeniz if (!isY(x)) {...}için bir işlev oluşturmak faydalı olacaktır.

Ben bir daktilo acemi, ve ben bu S / O soruya son birkaç hafta içinde bir sürü kez çarptı, bu yüzden googlers için bunu yapmak için daktilo yolu böyle bir yazıtipi oluşturmaktır:

typeGuards.ts

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

kullanım

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

Bunun yazı tipinde uygun olmasının tek nedeni olduğunu ve düzenli js olmamasının tek nedeni, yazıtiplerinin ortak bir kural olduğu, bu yüzden onları diğer arabirimler için yazıyorsanız, bunları sınıflar için de yazmak makul / anlaşılabilir / doğaldır.

Dokümanlarda bunun gibi kullanıcı tanımlı tür korumalar hakkında daha fazla ayrıntı var

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.