Best way to "negate" an instanceof

JavaSyntax

Java Problem Overview


I was thinking if there exists a better/nicer way to negate an instanceof in Java. Actually, I'm doing something like:

if(!(myObject instanceof SomeClass)) { /* do Something */ }

But I think that a "beautiful" syntax to do this should exist.

Does anyone know if it exists, and how the syntax look like?


EDIT: By beautiful, I might say something like this:

if(myObject !instanceof SomeClass) { /* do Something */ } // compilation fails

Java Solutions


Solution 1 - Java

No, there is no better way; yours is canonical.

Solution 2 - Java

I don't know what you imagine when you say "beautiful", but what about this? I personally think it's worse than the classic form you posted, but somebody might like it...

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

Solution 3 - Java

You could use the Class.isInstance method:

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

... but it is still negated and pretty ugly.

Solution 4 - Java

Usually you don't want just an if but an else clause as well.

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

can be written as

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

Or you can write the code so you don't need to know if its a String or not. e.g.

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

can be written as

str = str.toString();

Solution 5 - Java

If you can use static imports, and your moral code allows them

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

And then...

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

This is just a fluent interface exercise, I'd never use that in real life code!
Go for your classic way, it won't confuse anyone else reading your code!

Solution 6 - Java

If you find it more understandable, you can do something like this with 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
}

Solution 7 - Java

ok just my two cents, use a is string method:

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

Solution 8 - Java

You can achieve by doing below way.. just add a condition by adding bracket if(!(condition with instanceOf)) with the whole condition by adding ! operator at the start just the way mentioned in below code snippets.

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

instead of

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

Solution 9 - Java

I agree that in most cases the if (!(x instanceof Y)) {...} is the best approach, but in some cases creating an isY(x) function so you can if (!isY(x)) {...} is worthwhile.

I'm a typescript novice, and I've bumped into this S/O question a bunch of times over the last few weeks, so for the googlers the typescript way to do this is to create a typeguard like this:

typeGuards.ts

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

usage

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

I guess the only reason why this might be appropriate in typescript and not regular js is that typeguards are a common convention, so if you're writing them for other interfaces, it's reasonable / understandable / natural to write them for classes too.

There's more detail about user defined type guards like this in the docs

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questioncaarlos0View Question on Stackoverflow
Solution 1 - JavamaericsView Answer on Stackoverflow
Solution 2 - JavaNatixView Answer on Stackoverflow
Solution 3 - JavadacweView Answer on Stackoverflow
Solution 4 - JavaPeter LawreyView Answer on Stackoverflow
Solution 5 - JavaPablo GrisafiView Answer on Stackoverflow
Solution 6 - JavaPaulView Answer on Stackoverflow
Solution 7 - JavatibiView Answer on Stackoverflow
Solution 8 - JavaDharmesh BaldhaView Answer on Stackoverflow
Solution 9 - JavaMr5o1View Answer on Stackoverflow