I've been playing with this and so far I haven't been able to find any way to hide or trick instanceof
into returning false
by hiding its type through layers of obfuscation, but that doesn't mean it's not possible since I'm far from the most knowledgeable person about Java. So I've come to ask the experts.
I've tried the following combinations, and in each case the instanceof
operator is able to identify the true/base type of the object.
public class Test {
public static void main(String[] args) {
Object o = new TestObject();
printType("Base Class", o);
o = (TestSuperObject)(new TestObject());
printType("Super Class", o);
o = (TestInterface)(new TestObject());
printType("Interface", o);
o = (TestInterface)((TestSuperObject3)(new TestObject3()));
printType("Interface on Super Class", o);
o = (TestSuperObject3)((TestInterface)(new TestObject3()));
printType("Super Class on Interface", o);
}
private static void printType(String testCase, Object o) {
System.out.println(testCase);
System.out.println("TestObject:" + (o instanceof TestObject));
System.out.println("TestObject2:" + (o instanceof TestObject2));
System.out.println("TestObject3:" + (o instanceof TestObject3));
System.out.println();
}
}
The classes are defined as...
public class TestObject extends TestSuperObject implements TestInterface
public class TestObject2 extends TestSuperObject implements TestInterface
public interface TestInterface
public class TestSuperObject
public class TestObject3 extends TestSuperObject3
public class TestSuperObject3 implements TestInterface
So basically, is there any way to hide this information or to somehow lose the type information? I don't ask because I have a reason to do it, but rather would like to know and be wary of it in the future if it is possible. Plus, I just find it interesting.
It is possible to confuse yourself with instanceof
but not the JVM.
classes with the same name but in different packages are not the same. This means you can do
// in one class
ClassA classA = new ClassA(); // package1.ClassA
another.test(classA);
// calls in another class
public void test(Object o) {
if (o instanceof ClassA) // package2.ClassA => false
using different class loaders the packages and o.getClass().getName()
are the same, but as the class loaders are different instanceof
return false.
null
and null instanceof ClassB
is always false, even though null
can be assigned to any reference type.So basically, is there any way to hide this information or to somehow lose the type information?
No it is not possible.
Each object has a real type, and Java's strong + static type system makes it impossible to alter the type of an object, or pretend that its actual type is different to what it is.
(It is hypothetically possible to drop into native code and subvert the Java type system, but the consequences of doing this are likely to be really bad ... crash-the-JVM bad.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With