1

Javaの変数のリンクにアクセスする方法がないことを私は知っています(&Cや&phpのように)。しかし、例えば私にはそのような仕事があります:

public class JustTest {

    private int n = 1;
    private int x = 10;

    public int[] getIntegers() {
        return new int[] { n, x };
    }

    public void filledInteger() {
        int[] vals = getIntegers();

        System.out.println("Before change");
        System.out.println(Arrays.toString(vals));

        vals[0] = 2;
        vals[1] = 20;

        System.out.println("After change");
        System.out.println(Arrays.toString(vals));

        System.out.println("Values of name & xml");
        System.out.println(n);
        System.out.println(x);

        System.out.println("calling getIntegers");
        System.out.println(Arrays.toString(getIntegers()));
    }

    public static void main(String[] args) {
        JustTest t = new JustTest();
        t.filledInteger();
    }

}

結果は次のとおりです。

Before change
[1, 10]
After change
[2, 20]
Values of name & xml
1
10
calling getIntegers
[1, 10]

そこで、クラスインスタンスの「n」フィールドと「x」フィールドの値を変更したいと思います。まっすぐに設定して(this-> n = 20;)これを行うことはできません。これは、自分が持っているフィールドがわからない場合があるためです。getIntegersメソッドのみが知っています。

(このコードではありませんが、たとえば、独自のフィールドを持つ子クラスがあり、親クラスには、子クラスの指定されたプロパティを変更する必要があるメソッドfilledInteger()があります(彼はこのプロパティについて、メソッドgetIntegersから知っています。親クラスで抽象化し、子クラスで実装します))

これは、phpのリンクを使用した単純な実装(継承なし)です

<?php


class JustTest {

    private $n = 1;
    private $x = 10;

    public function getIntegers() {
        return array( &$this->n, &$this->x );
    }

    public function filledInteger() {
        $vals = $this->getIntegers();

        echo("Before change" . "<br/>");
        echo(print_r($vals, true) . "<br/>");

        $vals[0] = 2;
        $vals[1] = 20;

        echo("After change" . "<br/>");
        echo(print_r($vals, true) . "<br/>");

        echo("Values of n & x". "<br/>");
        echo $this->n , "<br/>";
        echo $this->x , "<br/>";

        echo("call getIntegers again" . "<br/>");
        echo(print_r($this->getIntegers(), true) . "<br/>");
    }

}

$t = new JustTest();
$t->filledInteger();

?>

結果は次のとおりです。

Before change
Array ( [0] => 1 [1] => 10 ) 
After change
Array ( [0] => 2 [1] => 20 ) 
Values of n & x
2
20
call getIntegers again
Array ( [0] => 2 [1] => 20 )

それが私がまさに必要としているものです。私はあなたが理解したことを願って、Javaでこれをどのように実装するのか興味があります。

次の例:

public abstract class ParentTest {
        abstract int[] getIntegers();

        public void fillIntegers(int[] newIntegers) {
            int[] integersOfChild = getIntegers();

            for (int i = 0; i < integersOfChild.length; i++) {
                integersOfChild[i] = newIntegers[i];
            }
        }
    }

    public class ChildTest extends ParentTest {

        private int x;
        private int y;

        @Override
        int[] getIntegers() {
            return new int[] {x, y};
        }

    }

    public class UseTest {
        void main() {
            List<ParentTest> list;

            for (ParentTest item : list) {
                item.fillIntegers(myItegers);
            }
        }
    }

これが私に必要なものです。ParentTestインスタンスのリストがあり(ChildTest、ChildTest2、ChildTest3の場合がありますが、すべてParentTestの子です)、すべてのフィールドに整数値を入力する必要がありますが、リストインスタンスの項目がChildTest、またはChildTest2、またはChildTest3クラス

4

5 に答える 5

1

これを Java で実装するにはどうすればよいですか?

Reflection API を介して大きな苦痛を伴います。このようなコードを書きたい場合は、別の言語を使用することをお勧めします。

代わりに Groovy でのプログラミングを検討してください。配列構文を使用して、クラス メンバーに名前で直接アクセスできます。t["n"] = 2; これは従来の Java コードで機能するため、この使用法をサポートするために TestClass を変更する必要はありません。

于 2012-05-04T20:56:30.653 に答える
1

あなたが話している概念は、参照渡しと呼ばれます。Java はほとんどの場合、Java を放棄しました。ここで見られるような副作用が多すぎます。

問題は、残念ながらここでこれを行うことはできませんが、意図しない膨大な数のバグがリリースされるのを実際に防いでいることです。

于 2012-05-04T20:57:26.623 に答える
0

リフレクションなしで個々のフィールドを実行することはできませんが、コレクションの内容を変更することはできます。これは意図した動作ではなく、コレクションを使用する際に注意する必要があることに注意してください。

これは 5 3 2 4 2 4 を出力します

public class Test
{
  public Vector<Integer> args = new Vector<Integer>();

  public void fillArgs()
  {
    args.add(5);
    args.add(3);
  }
  public Vector<Integer> getArgs()
  {
    return args;
  }

  public static void main(String args[])
  {
    Test s = new Test();

    s.fillArgs();
    Vector<Integer> temp = s.getArgs();
    for (Integer i : temp)
      System.out.println(i);
    temp.setElementAt(2, 0);
    temp.setElementAt(4, 1);
    for (Integer i : temp)
      System.out.println(i);
    for (Integer i : s.getArgs())
      System.out.println(i);
  }

}
于 2012-05-04T21:09:17.510 に答える
0

そのようなものはどうですか:

public final class JustTest {

    private final Map<String, Object> fields;

    public void filledInteger() {
        System.out.println("Before change\n" + this.fields);

        fields.put("N", 2);
        fields.put("X", 20);

        System.out.println("After change\n" + this.fields);

        System.out.println("Values of name & xml\n" + fields.get("N")
           + "\n" + fields.get("X"));
    }

    private JustTest() {
        this.fields = Maps.newHashMap(); // guava
        fields.put("N", 1);
        fields.put("X", 10);
    }

    public static void main(String[] args) {
        final JustTest t = new JustTest();
        t.filledInteger();
    }
}
于 2012-05-04T21:00:18.500 に答える
0

あなたのphpの例は、intの配列ではなく、intポインターの配列を返します。これはJavaでできることではありません。実際、これはJavaでやりたいことではありません。ユースケースを提示すると、問題を解決するためのより良い方法が見つかる可能性があります。

他の人が影響を与える可能性があり、メンバー変数として含まれているオブジェクトを返したい場合は、それを行います。ArrayList、HashMap など、ニーズに合うものはたくさんあります。他の誰かのクラスを与えられ、彼らのコードに鼻を突っ込まなければならない場合は、次のようにして彼らのプライベート宣言を回避できます。

public void setN(JustTest j, int n) {
    //You would handle some exceptions here also
    Field f = JustTest.class.getDeclaredField("n");
    f.setInt(j, n);
}
于 2012-05-04T21:02:26.153 に答える