5

私はこれで遊んでいますが、これまでのところ、難読化の層を介してそのタイプを隠すことで、隠したり、だましinstanceofて返す方法を見つけることができませんでしたが、それは、私が遠く離れているため、それが不可能であることを意味するものではありませんfalseJavaに最も精通した人物。そこで専門家に聞いてみました。

次の組み合わせを試しましたが、いずれの場合も、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

4 に答える 4

4

JVMと混同することは可能です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()は同じになりますが、クラスローダーが異なるため、 instanceoffalseが返されます。

  • オブジェクトはnull、任意の参照型に割り当てることができますがnull instanceof ClassB、常にfalseです。null
于 2012-10-16T14:16:38.780 に答える
1

基本的に、この情報を非表示にしたり、何らかの形で型情報を失う方法はありますか?

いいえ、できません。

各オブジェクトには実数型があり、Java の強力な + 静的型システムにより、オブジェクトの型を変更したり、実際の型が実際の型とは異なるふりをしたりすることができなくなります。


(仮想的には、ネイティブ コードに落とし込んで Java 型システムを破壊することは可能ですが、これを行うと、非常に悪い結果が生じる可能性があります... JVM のクラッシュは悪いことです。)

于 2012-10-16T14:04:22.523 に答える
0

難読化ツールを使用してコードを実行できます。しかし、これは基本的に改名です。TestObjectは eg に名前を変更できますAが、instanceof Aそれでも正しい結果が返されます。

ところで: クラスに名前を付ける *オブジェクトは悪い考えです (オブジェクト指向言語では)。

于 2012-10-16T14:27:29.480 に答える
0

OPが本当に望んでいるものに依存しますが、これでうまくいくかもしれません。

基本的にクラスは非公開にしています。これは、object instanceof Classコードがコンパイルされないことを意味します (プライベート クラスのスコープ外)。

于 2012-10-16T14:31:49.963 に答える