🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

7回答

11834閲覧

staticクラス、staticメソッドの意味と利点

HelloWorld2

総合スコア32

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

1グッド

14クリップ

投稿2019/02/13 10:36

初歩的な質問失礼いたします。

クラスとメソッドにstaticを付けることにはどのような意味があり、メリットは何でしょうか?

自分で調べたところ、

staticクラス :インスタンスを作成しないクラスであることを明示する。(コンパイルエラーを発生させる) staticメソッド:インスタンスを作成せずに使える。

といった概要であることは理解できましたが、あまり利点を感じません。

何か上記以外に、staticにする必要性や利点があるのでしょうか?
staticクラス、staticメソッドって使う必要ないのでは・・・?と思っている次第です。

また、引数fugaを持つstaticメソッドhoge(stirng fuga)を、複数スレッドから呼び出した際、
他のスレッドのfugaの値を書き換えてしまったりしないのでしょうか?

以上、よろしくお願いいたします。
(タグが不適切でしたらすみません)

teityura👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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

swordone

総合スコア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

Simb

総合スコア118

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

HelloWorld2

2019/02/15 02:04 編集

Simbさんや他の方のご回答を受けて、下記の認識となったのですが、正しいでしょうか? インスタンスを生成する必要性=状態を持つ=インスタンス変数が存在する? ならば、インスタンス変数が存在しない場合、インスタンスを生成する必要性がない。また、インスタンス変数に影響を与えないメソッドの場合、インスタンスを生成する必要がない。(staticメソッドで良い) したがって、インスタンスを生成する1文を省略するために、staticメソッドを作成した方が良い。 (インスタンス作成したいことで使用するメモリも減ったりするのかしら) 上記認識ですが、訂正、補足等ございましたら、お願いいたします。
Simb

2019/02/14 11:35

インスタンスを生成する必要があるか(したほうが良いか)という話は、どう設計するか次第です。個々別々に状態を持つ必要があるからインスタンスを生成するというのは、1つの観点でしかありません。 例えば、電卓もAさん専用、Bさん専用に用意(インスタンスを生成する)しても問題ないわけです。 さて、上記の回答では答えていなかった、staticを用いることのメリットについてですが、リソースに着目すると分かりやすいかもしれません。 共有の電卓を1台だけ用意するのと、100人分用意するのでは、電卓を製造する時間が100倍必要です。インスタンスも生成するにはCPUコストがかかります。仮に、足し算をする度に使い捨てにする電卓を用意した場合(普通そんなことはしないと思いますが)インスタンスを生成する時間が全体の処理性能に影響を及ぼすかもしれません。 また、机の上に電卓を1台おいておくのか、100人分の100台を置いておくのかでは、他のことに使える机のスペースに差がでてきます。インスタンスはメモリ上に配置される為、多くのインスタンスを必要もなく生成すると、他で使うためのメモリが確保できなくなります。(実際にはページングという方法でやりくりしたり、使わなくなったインスタンスをガベコレでメモリ上から無くしたりしますが、割愛します) プログラムを書くという視点からだけではなく、実行時の視点も踏まえて設計を行う必要があるわけです。
HelloWorld2

2019/02/15 02:11 編集

なるほど、非常に納得のいく説明でした! インスタンス生成によるCPUコストやメモリが節約できるという点から、メソッドをstaticにする意味があるのですね! ということは、インスタンス変数に影響を与えないメソッドの場合、基本的にはstaticにした方が良いということでしょうか? ちなみにクラスをstaticにするメリットはあるのでしょうか?
Simb

2019/02/15 16:37

上記のコメントではstaticメソッドを用いることの分かりやすいメリットを示しましたが、このメリットだけを捉えてstaticで書いたほうが良いのかというとそうではありません。Java等はオブジェクト指向で書くべき言語ですが、極端な言い方をすればstaticメソッドはオブジェクト指向に合わないからです。自分ひとりでコードを書いている限りでは問題にならないかもしれませんが、多くの人がそのコード読み、改変を加えるものであるという前提に立つ必要があります。つまり、多くの人にとってそのコードが分かりやすいか、改変を加えやすいか、といったことも意識してコードを書く必要があるわけです。 上のコメントにも記載しましたが、プログラムを書くという視点や実行時の視点など、様々な要素を勘案した上で、最適なコード設計を行う必要があるわけです。 これまでの例で例えるならば、今回のプログラムでは電卓は共用する方が良いと判断したが、また別のプログラムでは個々別々のインスタンスを生成したほうが良いと判断することだってあるわけです。 どういうときにstaticを用いるのが良いのかを覚えるという考えではなく、staticの持つメリットを理解しておき、実際にコード設計を行う際に、メリット・デメリットを照らし合わせて判断できるようにするという考えを持ってもらうと良いかと思います。 また、staticクラスについてのメリットとのことですが、Javaにおいてはstaticクラスはあまり見かけない印象です。使ったとしてもインナークラスにstaticがついている程度ですが、この場合インナークラスとは呼び難く、実質的には全く別のクラスです。 あえてインナークラスのようにstaticクラスを書くことで、2つのクラスの結びつきが強いことを示す効果がありますが、同時に分かりにくさや読みにくさを招くので、私個人としてはあまりお勧めしません。
HelloWorld2

2019/02/18 01:33

常にstaticであるべきではなく、保守性やメリデメを鑑みて選択する必要がある点、承知いたしました。 ここまで、ご丁寧にご回答くださりありがとうございました。
guest

0

Math クラスのような計算結果を得るためにわざわざインスタンスを作る必要ない場合は明らかなメリットがあると思いますよ。

投稿2019/02/13 11:38

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

HelloWorld2

2019/02/14 09:14

明かなメリットとは何でしょうか? インスタンスを作成する1行の記載の省略でしょうか・・・?
退会済みユーザー

退会済みユーザー

2019/02/14 10:00 編集

それだけでも十二分なメリットと思えませんか?
HelloWorld2

2019/02/15 02:07

すみませんが、あまりメリットとは思えないです。 ただ、他の方の回答のようにCPUコストやメモリという観点でのメリットは感じることができました。
退会済みユーザー

退会済みユーザー

2019/02/15 03:00

コードを書くための手間が減るということを言っているのではないのですよ。
guest

0

システムは, 必ずしも統一されたメリットで作成されてはおりません.
当初メリットの有ったものが時間が立つと無くなるものもありますし, 新しい使い道を見出だされて使われるようになることもあります.
ある人にはメリットでも, 別の人には大したことではないと言うこともあります.(どの言語が'良い'か等の論争になります.)

オブジェクト指向であればオブジェクト(インスタンス)とメッセージ(メソッド)は基本要素です. これらの使用は否定できません.
(否定は出来ませんが, 使わないことも一応出来ます.)
ですが static は, 他の方々も仰られていますように, (Class オブジェクトをインスタンスと見なさなければですが)インスタンスを介しませんので, オブジェクト指向内では例外的な部分を記述するものと思います.
ですので, 無理に全てをご理解しようとせずに先に進まれたほうがよろしいかと思います.

投稿2019/02/15 18:26

jimbe

総合スコア13204

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

言語は Java ですが、類似の質問がありましたので、参考までに載せておきます。

staticなmethodのメリットとは
https://teratail.com/questions/13203

また、引数fugaを持つstaticメソッドhoge(stirng fuga)を、複数スレッドから呼び出した際、
他のスレッドのfugaの値を書き換えてしまったりしないのでしょうか?

この例で言えば fuga は値渡しされるので書き換えは起こりませんが、引数が参照渡しされるケースは注意が必要です。
ただし、スレッドセーフかどうかと static かどうかは別問題です。

投稿2019/02/13 12:38

nskydiving

総合スコア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
root_jp

総合スコア4666

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

HelloWorld2

2019/02/14 09:18

インスタンスが必要である場合とはなんでしょうか? staticメソッドにおいて、複数スレッドから同時に呼び出されても、他スレッドのfugaの値に影響を与えないならば、staticでも非staticでも良い気がするのですが・・・(インスタンスを生成するメリットがなんだかわからないです・・・)
HelloWorld2

2019/02/14 09:41

インスタンス変数への影響があるメソッドかどうか、という点ですかね? インスタンス変数への影響がない場合、staticにすべきと理解しました。 が、staticじゃなくてもいいのでは・・・?(staticにするメリットってあるのでしょうか・・・?)という考えです。
guest

0

例えばFactoryメソッドなどの需要があるためstaticメソッドの必要性はあると思います。

  • インスタンスを作るメソッドを提供する(生成されたインスタンスに対してメソッドを呼び出せない -> static)
  • コンストラクタだとそのクラスそのもののインスタンスを作ってしまう(実際に生成される値が子クラスのインスタンスにしたい場合がある)
  • コンストラクタだとインスタンスが生成されない条件がある場合のコントロールが難しい

そのクラスに属する「関数」であって特定のインスタンスに依存しないことでできることは増えると思います。

投稿2019/02/15 03:12

mather

総合スコア6759

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問