'Best way to "negate" an instanceof
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
Solution 1:[1]
No, there is no better way; yours is canonical.
Solution 2:[2]
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:[3]
You could use the Class.isInstance
method:
if(!String.class.isInstance(str)) { /* do Something */ }
... but it is still negated and pretty ugly.
Solution 4:[4]
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:[5]
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:[6]
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:[7]
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:[8]
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:[9]
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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | maerics |
Solution 2 | ThomasW |
Solution 3 | |
Solution 4 | Koray Tugay |
Solution 5 | Pablo Grisafi |
Solution 6 | |
Solution 7 | |
Solution 8 | Dharmesh Baldha |
Solution 9 | Mr5o1 |