2016-12-27 4 views
-1

私はJavaに慣れていないので、なぜこのようにプライベート属性の値をセッターを使わずに設定できるのだろうか? :これは合法である理由Javaでgetterを使用してプライベートクラス属性の値を設定するのはなぜですか?

class Example { 
    private int[] thing; 
    public void initialize() { 
     thing = new int[10]; 
    } 
    public int[] getThing() { 
     return thing; 
    } 
} 
class myclass { 
    public static void main(String args[]) { 
     Example e = new Example(); 
     e.initialize(); 
     e.getThing()[0] = 1; 
     System.out.println(e.getThing()[0]) // value is still 1... 
} 

私は本当に理解していない...

編集:私は、ものの価値はないものへの参照を返すようにe.getThing()を予想し、それがあっても"事"はプライベートなので、私はそれを直接変更することはできないと思った。

+0

他のクラス**のプライベートメンバー**に値を設定してもよろしいですか? –

+5

あなたは何を期待していますか? – AxelH

+0

物事を読ませたい場合は、私は2つの方法のうちの1つでこれを行います。 1)配列の守備的コピーを作成します。ここで、 'new'を使って別の配列を作成し、これを返します。 2)List(例えばArrayList )を代わりに使用し、 'Iterable'(すべてのリストによって実装されたインターフェース)を返します。 'Iterable'を使って実行できる唯一のことは、(iterable内のオブジェクトを集合体である場合には変更することはできますが)多かれ少なかれ反復することです。 – patrik

答えて

8

ゲッターからの配列への参照が公開されていて、配列の内容自体がであり、変更可能なのはです。つまり、変更することができます。したがって、上の例では、クラスのプライベート変数が保持する配列への参照を返します。その配列を修正すると、その変更された配列が常に返されるため、getterから転送されます。

これを回避するには、何 でし行う次のいずれかです。

  1. リターンあなたのゲッターを経由して、コレクションの読み取り専用のビュー。これは速いかもしれませんが、親オブジェクトが配列の内容を変更している間に反復すると、混乱する可能性があります。
  2. 防御コピーをゲッターで返します。これは、コールごとに新しい配列のコピーを返す意味し、これはあなたの下で変化しないだろうが、あなたは上記のご特定例では、各コール

のためにそれをコピーすることで、コストを払って、あなたは読み取りを作成することもできますあなたのinitialize()メソッド内でのみ収集し、この問題は起こりません。

私はあなたがきれいにする必要があると思います。 プライベート(つまり、参照変数はクラス外では使用できません)(返品するオブジェクトは変更可能です)。これらは2つの非常に異なる概念です。

+3

Downvotedなぜですか? –

+0

thx。私はe.getThing()がメモリ内の参照ではない値を返すと思って、直接変更することができ、最終的には任意のセッターをバイパスします。 – erebos007

2
private int[] thing; 

は、thingへの参照がプライベートであるため、クラス外からはアクセスできないと言います。幸いにも、あなたはゲッターを持っているので、参照を取得します。

配列は変更可能なので、配列の内容を変更できます。

ないは何を行うことができますがthing新しいを設定することです:

e.thing = new int[5]; 

、これはプライベートが何をするかです。

+0

'initialize'が他のクラスから呼び出されたときでも変数に値を割り当てることができる理由を説明していません。それが問題です。 – nvioli

+0

私はそうじゃないですか? –

+0

@BrianAgnewどういう意味ですか? – xenteros

-2

thingがプライベートであるという事実は、あなたが

Example e = new Example(); 
e.thing = new int[10]; 

は、しかし、あなたは別のクラスから呼び出すことができますので、公にinitializeを公開するために選択したことができないことを意味します。 initializeの実装の詳細は、Exampleクラスの作成者のみが知ることができます。その作者は、privateフィールドで必要なことをすることを含め、そのクラス内で自分が望むものを何でもできます。

+0

申し訳ありませんが、私はその部分を誤読しました。 – lexicore

+0

あなたはまだ質問をしていませんでした。 – lexicore

+0

私は混乱がクラスの外から「プライベート」フィールドを設定する能力に関するものだと思ったので、それは私が答えたものです。多分私はOPが混乱していたものを誤解したかもしれません。 – nvioli

0

これは、プライベートメンバーが定義されているクラスでのみ直接アクセスできるため、パブリックアクセサメソッドを提供しない限り、クラスの外部にアクセスすることができないからです。配列参照へのパブリックアクセサを提供しており、参照を取得した後に値を変更しています

関連する問題