0

ゲッター関数を使用して、Java のクラスのプライベート メンバーを直接変更する方法を見つける必要があります。このようなポインターを使用して C++ でこれを実行できることはわかっています。

class FooBar
{
    private:
        Foo foo;

    public:
        Foo* getFoo()
        {
            return &foo;
        }
}

次に、getFoo() がポインターを返すためfoo、パブリック関数を介してプライベート変数を直接操作できます (例: ) 。getFoo()getFoo()->callFunction();

だから私が知りたいのは、Javaでこれとまったく同じ効果を再現する方法があるということだけですか??....とにかく?

4

7 に答える 7

5
class FooBar {
    private Foo foo;

    public Foo getFoo() {
        return foo;
    }
}

Java のすべてのオブジェクト変数はオブジェクトへの参照であるため、「ロックされた」ポインターと考えることができます。ポインター演算を実行できないという意味で「ロック」されています。

于 2012-12-23T09:23:19.587 に答える
2

以来、Java にはPointer. しかし、gettersetterを使用してこれを行うことができます。

class myclass{
private myclass val;  // private field

//get the private field
public myclass getVal(){
return val;
}

//set/change the member field value
public void setVal(myclass val){
this.val=val;
}

}
于 2012-12-23T09:19:16.327 に答える
2

Java では、getter がオブジェクトへの参照を返すため、返されたオブジェクトのパブリック メソッドに依存してオブジェクトを変更できます。やりたいことを具体的に教えていただければ、さらに詳しく説明できます。例として、

getter がリストを返す場合、呼び出し元は add メソッドまたは remove メソッドを使用してリストを変更できます。

于 2012-12-23T09:20:05.657 に答える
1

ゲッターとセッターを提供する必要があります

class FooBar {

    private Foo foo;

    public Foo getFoo() {
        return foo;
    }

    public void setFoo(Foo foo) {
        this.foo = foo;
    }

}
于 2012-12-23T09:32:09.683 に答える
1

必要なものは、すでに示したように、単に getter を介してアクセスできます。いくつかの重要な詳細:

あなたが何かしたいなら

getFoo()->callFunction();

次のことを確認してください。

  • Fooクラスが表示されます (同じパッケージ内にいる場合はデフォルトの修飾子、呼び出し元がサブクラスの場合はprotected 、それ以外の場合はpublic )
  • callFunction() は可視です (同じルール)

あなたが何かしたいなら

getFoo().value = newValue;

値が変更可能であることを確認してください。つまり、クラス Foo は値を final として定義していません。

class Foo {
    // in this case value is immutable
    final Bar value;
}

最後のケースでは、コンパイラは「最後のフィールド Foo.value を割り当てることができません」と言うでしょう。

于 2012-12-23T10:44:14.077 に答える
0

C ++でも、これは悪い考えです。オブジェクトの割り当てが解除されると、ポインタが無効なメモリ位置を指すようになるためです。これが、Javaにポインタがない理由の1つです。アクセスされるメモリを不正なポインタから保護するため。したがって、Javaでは、プライベートフィールドへのすべてのアクセスは、通常はget / setの組み合わせを使用して、囲んでいるオブジェクト自体を介して行う必要があります。

ただし、set()を使用することはあなたが望む解決策ではないと思います。Object以外の共通の階層を共有しない、異なるクラスのオブジェクトのコレクションがあることが原因である可能性があります。この場合、考えられる解決策は、共通のインターフェースを作成して使用することです。このように、この共通のインターフェースを使用して、これらの異なるオブジェクトの参照を保管し、同じ共通の方法でそれらを操作できます。例えば:

static void test() {

    List<IntegerGetSet> list = new ArrayList<IntegerGetSet>();
    list.add (new A1(1));
    list.add (new B1(2));

    for (IntegerGetSet igs: list) {
        igs.set (igs.get() * 10);               
        System.out.println(igs.get()); 
    }
}

interface IntegerGetSet {   
    public int get();
    public void set (int i);
}

static class A1 implements IntegerGetSet {

    private int i;

    public A1 (int i) { this.i = i; }

    @Override
    public int get() {
        return i;
    }

    @Override
    public void set(int i) {
        this.i = i;
    }       
}

static class B1 implements IntegerGetSet {
    private int i;

    public B1 (int i) { this.i = i; }

    @Override
    public int get() {
        return i;
    }

    @Override
    public void set(int i) {
        this.i = i;
    }       
}

これらのクラスを変更できない場合は、さらに複雑なものを作成する必要があります。たとえば、別の投稿で提案されているようにReflectionを使用します。

于 2012-12-23T10:54:58.830 に答える
0

Java はPass by Value、より具体的にはPass a Reference by Valueです。これは、すべての参照型が次のように渡されることを意味します。

List<String> a = myObj.getList();
a.add("My String"); // this modifies the source list

List<String> b = new ArrayList<String>();
a = b; // this doesn't change the source list's reference

Java でプログラミングする場合、ほとんどの人は可能な限り最高レベルのカプセル化を試み、可変型を不変型に変換します (たとえば、コピー コンストラクターのイディオムを使用します)。これは、OOP 空間でプログラミングする良い方法です。

セッターがない場合は、Java の組み込みリフレクションを使用することをお勧めします。

public class Test {
    private String NAME = "OLD NAME";

    public String getName() {
        return this.NAME;
    }

    public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
        Test t = new Test();
        System.out.println(t.getName()); // OLD NAME

        Field f = t.getClass().getDeclaredField("NAME");
        f.setAccessible(true); // allows access to private field 
        f.set(t, "NEW NAME");

        System.out.println(t.getName()); // NEW NAME
    }
}

ただし、リフレクションは高度なトピックであり、ほとんどの場合、不適切なプログラミングの兆候であることに注意してください。

于 2012-12-23T09:48:26.270 に答える