アプリ版:「スタンプのみでお礼する」機能のリリースについて

こんにちは。Javaをはじめてだいぶ経ちますが、未だにタイトルの疑問が解決しきれません。
staticにした方が呼び出すときに便利なような気がしますが、そうするとstaticにしない理由は何なのでしょうか?基本的な質問かと思いますが、どなたかよろしくお願いします。

A 回答 (8件)

確かに"副作用"のない場合、staticにしたほうが呼び出す時に便利です。


数値aの絶対を求めるメソッドはstaticで
ans = Math.abs(a);
と出来るわけですが、こうできるのはabsメソッドの処理が引数の値の絶対値を求めるだけであり、このメソッド内で処理を完結できるからです。

staticにしない(できない)場合というのは
list = new ArrayList();
list.add(object);
のaddメソッドように、
オブジェクトの中身が変更される処理を持つメソッドはstaticにはできません。
このメソッド内で処理が完結するわけではなく、オブジェクトに影響を与えるからです。(←意図せずに影響を与えることを"副作用"と言ったりします)

staticに(できるが)しない場合というのは
staticメソッドはオブジェクトを生成する前から存在しているので、
(math = new Math()
として初めてmathオブジェクトがメモリ上に作られるわけですが、absメソッドは別にnew する前からメモリ上に存在しています)
必要な時だけメモリ上に展開したいメソッドの場合はstaticにしないことでしょう。

と、まぁ私は上のような基準でstaticにする、しないを判断しています。
出来るものはなるべくstaticにしていますが、呼び出しが便利だからと言う理由にくわえて、staticのメソッドですとこのメソッドを呼び出しても他に影響がないことを、メソッドを呼び出す人が確証できるので、その意味でstaticにします。
    • good
    • 1
この回答へのお礼

お礼が遅くなりすいません。
なるほど、staticでいいものは無理にインスタンスメソッドにしなくてもいいんですね、ありがとうございました。

お礼日時:2006/03/19 17:49

私の場合、クラスメソッド(=静的メソッド,staticメソッド)が如何なるものかについては、以下の過去ログにて十二分に理解できたのですが、今回の質問者さんは「Javaをはじめてだいぶ経」っているということもあり、あえて違った観点からの回答を試みます。

(というか、他の回答者さんとか、閲覧者さんへのアドバイスでもあるんですけど。)

http://oshiete1.goo.ne.jp/kotaeru.php3?q=188680

一般的に、クラスライブラリなどで分からないことがあった時には、よく「APIドキュメント」を利用したりしますよね。(各メソッドの引数の型や例外に、J2SDKのどのバージョンから対応しているのかなど・・。)ただ、こちらの方は、文法事項や概念などがあまり載っていなかったりします。そこで、「クラスメソッドって何?」とか、「何でインタフェースを使うの?」などのような疑問を解決するのにお勧めなのが「Java言語規定」です。

「Java Language Specification, version 1.0(日本語版)」
[財)日本規格協会 情報技術標準化研究センター(INSTAC)のマルチメディア/ハイパメディア調査研究委員会]
http://www.y-adagio.com/public/standards/tr_java …

「The Java Language Specification, Third Edition」
[サンの公式サイトより引用。全て英語ですが、最新バージョンです。]
http://java.sun.com/docs/books/jls/third_edition …

これによると、インスタンスメソッドとクラスメソッドの各々の特徴については、8.4.6.1や8.4.6.2などに載っていますが、要約すると以下のようになります。

インスタンスメソッド
→スーパクラス内で同じシグネチャをもつメソッドの上書き(override)が可能。
クラスメソッド
→スーパクラス内で同じシグネチャをもつメソッドの隠ぺい(hide)が可能。

インスタンスメソッドについて言えば、継承により単に親クラスのメソッドを呼び出すだけでなく、再び定義し直すことが可能ですし、クラスメソッドに関しては、どんな時でも同じ振舞いを保証しますよね。(java.lang.Math.absメソッドは、どのプログラマーがどんな記述をしようとも、実引数の絶対値を返しますね。)8.4.8.5では、「隠ぺいされたクラスメソッドの呼出し」に関するJavaプログラムも載っていますので、そちらの方も参考にされたら、と思います。

それ以外にも、13.4.18では、「バイナリの互換性」についての記述があります。今まで、クラスメソッドだったものをインスタンスメソッドに変更したりとか、はたまたその逆を行ったりすると、リンク時にIncompatibleClassChangeErrorとなってしまうとのことです。これなんかは、よくServletやJSPなどでソースプログラムの更新がうまく反映されない時などに、仕方なく一端、classファイルを全部削除後に再度、全コンパイルをしたらうまく表示される、といったことがあったりしますが、広い意味での「バイナリの互換性」に起因するものではないか、と思われます。

最後に、メモリとJVMとの関連性についてですが、こちらも実際には以下のようなサイトがあります。

「Java仮想計算機仕様書(The Java Virtual Machine Specification)」
http://java.sun.com/docs/books/vmspec/2nd-editio …

ただ、全部英語ということもあって、もう少し噛み砕いたのがいいんだけど・・・、という方々がいらっしゃるかもしれませんので、一応以下のサイトも載せておきます。

浅煎り珈琲 Java アプリケーション入門
パフォーマンス
4.JVM のメモリ構造
http://msugai.fc2web.com/java/perform/storage.html
    • good
    • 0

No.4 のかたの疑問に関して私なりの解釈ですが、たした次のようになっていたはずです。



static 変数はプログラム開始から存在するわけではありません。またstatic メソッドを含むクラスファイルも最初からJVMに読み込まれたりしません。

プログラムの実行中に、static メソッド(または変数)が最初に呼び出された時点でそのクラスファイルがメモリにロードされ、そのクラスのすべてのstatic変数がメモリに割り当てられます。

反対に寿命のほうはあまり自信がないのですが、static変数はいつまた利用されるかわからないため、JVMは「このstatic変数はもう使われない」と判断することが不可能であり、プログラム終了までメモリを占有したままになったような・・・。
    • good
    • 0

#2>基本的にメソッドはインスタンスの状態を変えるものか、あるいはインスタンスの状態によって振る舞いを変えるものだと思う



kztkさんの意見に賛成。awtやswingやファイル入出力などは、インスタンス無しには何も出来ないです。

デザインパターンの本を持ってますが、staticが付いてるのは、main()とSingleton実装のためのメソッドだけで、他のパターンクラスでは、みなインスタンスメソッドだけでした。
また、これらのインスタンスメソッドはstaticにしたら、バグになるかエラーになるか、デザインパターンとして破綻するかだと思われます。(趣味のプログラマーが偉そうなこというのもなんですが、そう思いました)

私がほとんどのメソッドをstaticにしない理由:staticには出来ないから。
どーしても、staticである必要がある時のみ、staticにする。
    • good
    • 0

staticにしたほうがよいとか、そういうメソッドが多いということは、設計的に構造化プログラミングになってると思われます。


Javaはオブジェクト指向プログラミングなので、そういった場合は設計が悪いのではないかという疑いがでてきます。
    • good
    • 0

はじめまして。

質問とはちょっとずれているかもしれませんが、
私は以下のような疑問をもち、いろいろと調べていたところです。

staticメソッドは実行開始(あるいは最初の使用)から実行終了まで
メモリ展開されている状態であるというのは本当なのか?

上記が本当となればstaticメソッドはむやみに使うのはメモリの無駄使いと
言われてしまうと思うです。というわけで、調べた結果なんですが、
自信はありませんが、どうもウソなんじゃないかと思っています。
参考にさせていただいたのは下記のURLです。
参考URLの内容を要約する能力はないのでぜひ読んでください。
staticメソッドがメモリに存在し続けるというのは
static変数がプログラムの実行開始から終了までメモリに存在し続ける
ことからの類推がもたらす勘違いなのではないかと思います。
素朴に考えてみてもstaticメソッドはIntegerやMathから自作のstaticメソッドまで
大量にあると思うのですが、これらのメソッド(関数)が本当に最初から
すべてメモリ展開され、その後、捨てられることなくプログラムの終了まで
メモリに存在し続けるというのはあまりに非効率で、Java(あるいはVM?)の
設計者がそんなことしているとは思えません。

以上、書いてはみたものの、実は私は経験のかなり浅いものでして
ぜひこのようなことに詳しい方にコメントをいただければと思います。

参考URL:http://question.woman.excite.co.jp/kotaeru.php3? …
    • good
    • 0

「インスタンスメソッドにしなければならない理由」


がないときはstatic。
---
>staticにしない理由は何なのでしょうか


プログラマが「その必要性を感じた時に」インスタンスメソッドにする。
「必要性を感じない」なら、
試しにそれをstaticにしてみるとよい。
    • good
    • 0

私は始めて覚えた言語がJavaですが、



>staticにした方が呼び出すときに便利

という感覚はあまり分かりません。
基本的にメソッドはインスタンスの状態を変えるものか、あるいはインスタンスの状態によって振る舞いを変えるものだと思うので、私がstaticにするのは
・ユーティリティ系の関数
・インスタンスを作成したり返したりするメソッド
 (getInstance()やcreateXX()など)
くらいです。前者などはむしろ逆に"クラス名."をつけなければならないのが鬱陶しいと感じるほどです。
 他にどういうときにstaticになるか考えて見たのですが、#1さんのあげたArrayListで、addをstaticにしてArrayList.add(list, object)のように設計していたら、staticばっかりになっていたでしょうね。

質問者さんがどういう使われ方をして便利だと感じられているのかに興味があります。

この回答への補足

ご回答ありがとうございます。呼び出すときに便利、と言うのは、例えばオブジェクトを格納する変数の名前を何にすべきか考えなくていいのが楽です。仮に考えずにとりあえずobjとかにしてしまうと、もし将来何かほかの呼び出しを追加して拡張したときはobj2, obj3…と増えていくとまずいなぁとか。またこのオブジェクトが大量に作られることはなかろうかとか、Singletonにした方がいいんだろうかとか、何かと気になります。
あとできればstaticにして、staticが無理なときはインスタンスメソッドにするというのも、設計しだいである程度無理やりstaticにすることが出来る気がします。そうすると、インスタンスを生成する機会はけっこう少ないように思います。まぁ私はまだそんなに設計になれてるわけではないので、それは設計が悪いと言われればそれまでですが…。
また、クラス名をつける作業ですが、いつもeclipseでやってるので、私はあんまり苦になりません。それより適切な変数名をいちいち考えるほうが面倒です。
あんまりstaticを増やしすぎると(getInstance()とかは除き)だんだんオブジェクト指向から離れていくような気がしますが、どうでしょう?やっぱり設計の問題でしょうか?

補足日時:2006/03/05 12:35
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!