是否有任何级别的混淆可以“欺骗”instanceof?

时间:2012-10-16 13:59:36

标签: java casting polymorphism instanceof

我一直在玩这个,到目前为止,我还没有找到任何方法隐藏或欺骗instanceof通过隐藏层次的混淆隐藏其类型来返回false,但是并不意味着它不可能,因为我远远不是最了解Java的人。所以我来问专家。

我尝试了以下组合,并且在每种情况下instanceof运算符都能够识别对象的真/基类型。

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

}

这些类被定义为......

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

所以基本上,有没有办法隐藏这些信息或以某种方式丢失类型信息?我没有问,因为我有理由这样做,但是如果 可能的话,我希望知道并在将来保持警惕。另外,我觉得它很有趣。

4 个答案:

答案 0 :(得分:4)

可能会将自己与instanceof混淆,但不会与JVM混淆。

  • 具有相同名称但在不同包中的类不一样。这意味着你可以做到

    // 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 
    
  • 使用不同的类加载器,包和o.getClass().getName()是相同的,但由于类加载器不同instanceof返回false。

  • 对象为nullnull instanceof ClassB始终为false,即使可以将null分配给任何引用类型。

答案 1 :(得分:2)

  

所以基本上,有没有办法隐藏这些信息或以某种方式丢失类型信息?

不,这是不可能的。

每个对象都有一个真实的类型,Java的强+静态类型系统使得无法改变对象的类型,或假装它的实际类型与它不同。


(假设有可能放入本机代码并破坏Java类型系统,但这样做的后果可能非常糟糕...... JVM崩溃了。)

答案 2 :(得分:0)

您可以通过混淆器运行代码。但这基本上是重命名。可以将TestObject重命名为例如A,但instanceof A仍会返回正确的结果。

BTW:命名你的类*对象是一个坏主意(用面向对象的语言)。

答案 3 :(得分:0)

这取决于OP真正想要的是什么,但this可能会这样做。

基本上我把这个课私有化了。这意味着任何object instanceof Class代码都不会编译(在私有类的范围之外)。