初歩的な質問失礼いたします。
クラスとメソッドにstaticを付けることにはどのような意味があり、メリットは何でしょうか?
自分で調べたところ、
staticクラス :インスタンスを作成しないクラスであることを明示する。(コンパイルエラーを発生させる) staticメソッド:インスタンスを作成せずに使える。
といった概要であることは理解できましたが、あまり利点を感じません。
何か上記以外に、staticにする必要性や利点があるのでしょうか?
staticクラス、staticメソッドって使う必要ないのでは・・・?と思っている次第です。
また、引数fugaを持つstaticメソッドhoge(stirng fuga)を、複数スレッドから呼び出した際、
他のスレッドのfugaの値を書き換えてしまったりしないのでしょうか?
以上、よろしくお願いいたします。
(タグが不適切でしたらすみません)
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答7件
0
staticにする必要性というよりむしろ、インスタンスを複数必要とするかどうかという観点から考えるべきかと思います。
そもそもインスタンスの役割とは何か?
値の型にはプリミティブ型(int,longなど)と参照型があり、インスタンスは参照型に属します。
プリミティブ型が単一の値を持つのに対し、参照型の多くは複数の値を構造的に持ちます。
例えば、Humanという、名前、身長、体重などを情報を持ったクラスを考えます。
java
1class Human { 2 String name; 3 double height; 4 double weight; 5}
当然、人の名前、身長、体重は人によって異なります。そのため、インスタンスを作成して異なる情報を持たせる必要が出てきます。
「あなたの名前は?」という質問は、質問する相手が異なれば違う答えが返ってきますよね?
これをJavaのプログラム上で表現すると、名前を取得するメソッド(仮にgetName()
とする)は、その実行する対象のインスタンスが異なれば違う結果が返ってくる(可能性がある)ということになります。
java
1// Humanクラスに名前、身長、体重を与えるコンストラクタがあるものとして 2Human takashi = new Human("たかし", 165.0, 55.0); 3Human akira = new Human("あきら", 159.0, 50.0); 4System.out.println(takashi.getName()); //たかし 5System.out.println(akira.getName()); //あきら
staticメソッドの場合は?
一方staticメソッドはどうでしょう。
例えばMathクラスにあるsqrt
メソッドですが、これは引数に与えられた数値の平方根を求めるものです。これは引数が同じであれば、誰が計算しようと結果は同じになります。つまり、結果が引数以外に依存しません。であれば、前述したようなインスタンスごとに結果が異なるとする必要はなく、むしろインスタンスを作成することにより、結果がインスタンスの内容に依存すると読めてしまう可能性すらあります。
また別の例では、Calendar.getInstance()
というメソッドがあります。これは現在の時刻を表すCalendarオブジェクトを取得するというものです。この「現在の時刻」というのは、特定の誰か、あるいは何かごとに異なるということはなく、呼び出した瞬間に一意に決まるものです。ということはこれもインスタンスから呼び出すと、実際はその内容に関係ないにも関わらず、インスタンスの情報依存のなにがしかが返ってくるという誤解を与える可能性があります。
このようなメソッドは、特定のインスタンスの情報に依存しないと明示したほうが、コードを読む側に誤解を与えずに済むのです。そのために使われるのがstatic修飾子なのです。
投稿2019/02/15 02:50
総合スコア20669
0
ベストアンサー
先の方の回答にもある通り、インスタンスを生成する必要がある場合とそうでない場合の違いについて理解されているかではないでしょうか。
Java
1public class Car { 2 private Tire[] tires; 3 public void drive(){}; 4 : 5} 6 7public static void main(){ 8 Car carA = new Car() 9 Car carB = new Car(); 10 11 carA.drive(); 12 carB.drive(); 13}
上記のように車クラスが存在する場合、Aさんの乗る車とBさんの乗る車はそれぞれ別の個体です。
それぞれの車毎にタイヤは存在しますし、それぞれの車を運転することができるわけです。
このような場合はインスタンス化する訳です。
一方で、Aさんが足し算する際に使用する電卓と、Bさんが足し算する際に使用する電卓は別の個体として必要でしょうか?
これはもちろんそれぞれ専用の電卓を用意しても構いませんが、同じ電卓を使うときに融通しあっても問題ないはずです。
Java
1public class Calculator{ 2 public static int add(int x, int y){ 3 return x + y; 4 } 5} 6 7public static void main(){ 8 int result1 = Calculator.add(1, 2); 9 int result2 = Calculator.add(3, 5); 10}
尚、電卓において1回前の計算結果を用いるような機能があった際、AさんとBさんが同じ電卓を融通しあって使っているとどうなるでしょう?
この場合、他に電卓を使っている人が居ないかを確認せずに使用すると、その電卓の前回の計算結果が使用者自身が計算した結果であることの保証ができなくなります。
Java
1public class Calculator{ 2 private static int preResult; 3 4 public static int addMemory(int x){ 5 preResult = preResult + x; 6 return preResult; 7 } 8}
投稿2019/02/13 14:12
総合スコア118
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/02/14 11:35
2019/02/15 02:11 編集
2019/02/15 16:37
2019/02/18 01:33
0
Math クラスのような計算結果を得るためにわざわざインスタンスを作る必要ない場合は明らかなメリットがあると思いますよ。
投稿2019/02/13 11:38
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/02/14 09:14
退会済みユーザー
2019/02/14 10:00 編集
2019/02/15 02:07
退会済みユーザー
2019/02/15 03:00
0
システムは, 必ずしも統一されたメリットで作成されてはおりません.
当初メリットの有ったものが時間が立つと無くなるものもありますし, 新しい使い道を見出だされて使われるようになることもあります.
ある人にはメリットでも, 別の人には大したことではないと言うこともあります.(どの言語が'良い'か等の論争になります.)
オブジェクト指向であればオブジェクト(インスタンス)とメッセージ(メソッド)は基本要素です. これらの使用は否定できません.
(否定は出来ませんが, 使わないことも一応出来ます.)
ですが static は, 他の方々も仰られていますように, (Class オブジェクトをインスタンスと見なさなければですが)インスタンスを介しませんので, オブジェクト指向内では例外的な部分を記述するものと思います.
ですので, 無理に全てをご理解しようとせずに先に進まれたほうがよろしいかと思います.
投稿2019/02/15 18:26
総合スコア13204
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
言語は Java ですが、類似の質問がありましたので、参考までに載せておきます。
staticなmethodのメリットとは
https://teratail.com/questions/13203
また、引数fugaを持つstaticメソッドhoge(stirng fuga)を、複数スレッドから呼び出した際、
他のスレッドのfugaの値を書き換えてしまったりしないのでしょうか?
この例で言えば fuga は値渡しされるので書き換えは起こりませんが、引数が参照渡しされるケースは注意が必要です。
ただし、スレッドセーフかどうかと static かどうかは別問題です。
投稿2019/02/13 12:38
総合スコア6500
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
JavaとC#ではstaticクラスの意味が異なるので何とも言えませんが、共通して言える事は
状態(インスタンス変数)を持たないクラスであれば、基本staticであるべきだと思います。
状態を扱わない単なる共通関数(メソッドではない)などはstaticにすべきだということです。
しかし、状態を持たないクラスというのはオブジェクト指向に反しており、あまり作る機会はないはずです。
おそらくstaticがどうのこうのよりインスタンスの必要性が理解できていないのだと思います。
インスタンスが必要であれば、そのようにクラス設計をすればいいですし、
不要なのであればstaticにすべきです。
また、引数fugaを持つstaticメソッドhoge(stirng fuga)を、複数スレッドから呼び出した際、
他のスレッドのfugaの値を書き換えてしまったりしないのでしょうか?
fugaはローカル変数です。
ローカル変数はスレッドスタックに積まれていきます。
スレッド毎に持っているということです。なのでスレッドセーフです。
投稿2019/02/13 12:24
編集2019/02/13 12:27総合スコア4666
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/02/14 09:18
2019/02/14 09:41
0
例えばFactoryメソッドなどの需要があるためstaticメソッドの必要性はあると思います。
- インスタンスを作るメソッドを提供する(生成されたインスタンスに対してメソッドを呼び出せない -> static)
- コンストラクタだとそのクラスそのもののインスタンスを作ってしまう(実際に生成される値が子クラスのインスタンスにしたい場合がある)
- コンストラクタだとインスタンスが生成されない条件がある場合のコントロールが難しい
そのクラスに属する「関数」であって特定のインスタンスに依存しないことでできることは増えると思います。
投稿2019/02/15 03:12
総合スコア6759
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。