인스턴스를 '부정'하는 가장 좋은 방법


409

instanceofJava에서 부정적이거나 더 좋은 방법이 있는지 생각하고있었습니다 . 실제로, 나는 다음과 같은 일을하고있다 :

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

그러나 나는 이것을하기위한 "아름다운"문법이 존재해야한다고 생각한다.

누구나 존재하고 구문이 어떻게 보이는지 아십니까?


편집 : 아름답게, 나는 이런 식으로 말할 수 있습니다 :

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

24
나는 instanceof너무 많은 우선 순위 규칙을 싫어 ...
luiscubal

4
항상 다음과 같은 변수를 만들 수 있습니다 boolean strIsString = str instanceof String;.
vaughandroid

예, @Baqueta는 옵션입니다. 그러나 한 구문 또는 다른 구문에서 메모리 사용시 어떤 차이가 발생할 수 있습니까?
caarlos0

2
건설적인 의견은 어떻습니까?
Louth

2
Java 제작자는 notinstanceof 라는 새로운 키워드를 도입 할 수 있습니다 . 그냥 내 두 센트 ^^
Stephan

답변:



132

나는 당신이 "아름다움"이라고 말할 때 당신이 무엇을 상상하는지 모르지만 이것에 대해 어떻게 생각합니까? 나는 개인적으로 당신이 게시 한 고전 양식보다 나쁘다고 생각하지만 누군가는 그것을 좋아할 것입니다 ...

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

2
이중 논리 != true에 대해서는 == false: D 대신 사용할 수 있습니다 .
jupi

이것이 if(!(str instanceof String)) 올바른 방법 임을 이해하는 데 도움이 되고 대안을 생각해야합니다.
Vikash

나는 그것을 읽는 동안 금속 스택을 만들 필요가 없기 때문에이 솔루션을 좋아합니다!
JaM

59

다음 Class.isInstance방법을 사용할 수 있습니다 .

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

...하지만 여전히 부정되고 꽤 추악합니다.


5
괄호가 너무 많으면 코드가 못 생깁니다 (IMHO).
caarlos0

이것이 느리지 않습니까?
maxammann

4
이것은 다른 행동을 가지고 있습니다. instanceof 키워드에는 서브 클래스가 포함되어 있지만 메소드는 그렇지 않습니다. 동작을 복제하기 위해 Class.isAssignableFrom을 사용해야합니다.
Chris Cooper

7
@ChrisCooper 사실이 아닙니다 :this method returns true if the specified Object argument is an instance of the represented class (or of any of its subclasses)
Natix

24

보통 그냥 싶지 않아 if하지만 else절뿐만 아니라.

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

로 쓸 수 있습니다

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

또는 코드를 작성하여 문자열인지 여부를 알 필요가 없습니다. 예 :

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

로 쓸 수 있습니다

str = str.toString();

12

정적 임포트를 사용할 수 있고 도덕적 코드로 허용되는 경우

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

그리고...

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

이것은 유창한 인터페이스 연습입니다. 실제 코드에서는 절대 사용하지 않을 것입니다!
고전적인 방법으로 가십시오. 다른 사람이 코드를 읽는 것을 혼동하지 않습니다!


나는 정적 수입품을 좋아하지 않습니다. 어쨌든 도와 주셔서 감사합니다 :)
caarlos0

4

더 이해가 잘된다면 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
}

1
Java 11에서는 작동 if (Predicate.not(isInstanceOfTheClass).test(myObject)) { ...합니다. 더 나아지지는 않지만, 잘 작동합니다!
Patrick M

3

좋아 내 두 센트, 문자열 방법을 사용하십시오 :

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

아래 방법으로 수행 할 수 있습니다 . 아래 코드 스 니펫에서 언급 한대로 시작 부분에 연산자를 if(!(condition with instanceOf))추가하여 전체 조건에 대괄호 를 추가하여 조건을 추가 하십시오 !.

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

대신에

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

0

나는 대부분의 경우 if (!(x instanceof Y)) {...}최선의 접근법이지만, 어떤 경우에는 isY(x)함수를 생성하여 if (!isY(x)) {...}가치가 있다고 동의합니다 .

나는 타이프 스크립트 초보자이며 지난 몇 주 동안이 S / O 질문에 여러 번 부딪 쳤습니다 .Google 직원에게는 타이프 스크립트를 작성하는 방법은 다음과 같이 타이프 가드를 만드는 것입니다.

typeGuards.ts

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

용법

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

이것이 일반적인 js가 아닌 typescript에 적합 할 수있는 유일한 이유는 typeguards가 일반적인 규칙이기 때문에 다른 인터페이스를 위해 작성하는 경우 클래스에 대해서도 작성하는 것이 합리적이고 이해할 수 있으며 자연 스럽습니다.

문서에 이와 같은 사용자 정의 유형 가드에 대한 자세한 내용이 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.