- PR -

staticメソッドに関して

投稿者投稿内容
英-Ran
ベテラン
会議室デビュー日: 2002/06/12
投稿数: 55
投稿日時: 2002-07-31 17:33
asipさん。ちゃんとmokenさんとayumさんの指摘に答えてはくれませんか。

> APIリファレンスをきちんとみましょう!

と言っていますが、APIリファレンスには、
・空文字列で無い場合はトリミングした結果を新規のStringオブジェクトとして返す
・空文字列の場合は、新規にオブジェクトを作るようなことはしない
と書いてあり

> if (param == null || param.trim().equals("")) {

で何ら問題がないように思えます。APIリファレンスの問題の個所を示していただけないでしょうか。
moken
会議室デビュー日: 2002/07/22
投稿数: 6
お住まい・勤務地: 東京都三鷹市
投稿日時: 2002-07-31 17:57
理解できました。ayumさん、ありがとうございました。
Staticメソッドの話からそれてしまい、すいませんでした。
私も、H2さん、英-RANさん同様、ご質問の様な状態は、起こらないと思います。
もし起きるのであれば、H2さんのご指摘のような状況が考えられます。
KnoledgeBaseとして、SunのJavaプログラマ認定試験でも受けよう!
と思ってみたり、みなかったり。
asip
ベテラン
会議室デビュー日: 2001/12/27
投稿数: 77
投稿日時: 2002-08-01 09:20
APIリファレンスの記述の解釈を間違ってました。"参照"という表現にばかされてました。
ゆうさんのロジックで問題ありません。僕の勘違いです。

staticメソッドについてひとこと。

staticメソッド内部からは外部のstaticメソッドあるいは外部のstatic変数にしか
アクセスできません。
staticメソッド内部から外部のstatic変数を参照している場合には問題が起こりえます。
static変数はクラスのメモリロード時に一回だけ初期化されるからです。
(インスタンス変数はオブジェクト生成時に初期化されます。)

[ メッセージ編集済み 編集者: asip 編集日時 2002-08-01 09:21 ]
ゆう
常連さん
会議室デビュー日: 2001/12/10
投稿数: 33
投稿日時: 2002-08-02 00:06
色々な指摘ありがとうございます。

ちなみに
checker.isIndispensable("hoge");ではなく
Checker.isIndispensable("hoge");でした。

>#何故そう思ったのかを書いた方が疑問が解けるかもしれませんよ。

ところで、なぜそのようなことを思ったかというと
クラスメソッドはインスタンスかしていないので、
ひとつの実態のようなもの?を共有していると考えたからです。
同時に同じ実態を利用すると先に呼び出した時のパラメータが
後から呼びだしたパラメータによって上書きされないのかと思っただけです。

ということは、クラスメソッドを使うことの利点は
可読性があがるということしかないのでしょうか?

ちなみにSUNのプログラマの資格は持っていますが、細かいところまでは試験では問われませんし、あの資格を持っていてもJAVAの知識はたかがしれてるってことですね。
しょむ
ぬし
会議室デビュー日: 2001/09/06
投稿数: 430
投稿日時: 2002-08-02 02:04
本題に戻ったようですね(w

「パラメータの上書き」を見ると、関数に再入可能かという話のような気がします。
static かどうかはおいといて。
けっこう説明めんどうですね…

結論から言えば、static かどうかにかかわらず、複数スレッドからのアクセスが起こる場合は変なことが起こる可能性があります。ちゃんと同期をとりましょう。

「引数に渡したものがいつのまにか別スレッドで書き換えらる」というのは、int のような premitive なものではありえません。呼び出しごとにコピーを作りますので。
また、最初にあげられている String のように不変(生成したら変更不可)なものの場合も、そういう心配は要りません。
それから、スレッド間で共有されないもの(含引数)にしかアクセスしないメソッドもだいじょうぶです(static な変数類はスレッド間で共有される)。

このへんはマルチスレッドのお話なので、適当に勉強してください。

で、クラスメソッドの利点の話(これが本題?)。

インスタンスを必要としないメソッドをクラスメソッドにすれば、インスタンス化というコストのかかる処理を減らせます。
あとは… クラスメソッドの挙動は個々のインスタンスの状態には依存しないことが保証される(もちろんクラス変数には依存する)、ぐらい…?

…う〜ん…いろいろ考えてみたけどこれに尽きる気がしてきた…
英-Ran
ベテラン
会議室デビュー日: 2002/06/12
投稿数: 55
投稿日時: 2002-08-02 09:25
staticメソッドは、java.lang.Runtimeとかjava.awt.Toolkitみたいに基本的に(実行中に)ひとつしか存在しない場合によく見ますかねえ(Singletonパターン)。

Mathクラスのように状態を持たないため、インスタンスを生成する必要がそもそもない場合にも使いますが、staticメソッドの存在理由の説明としては弱いような気がしてます。

私は基本的にpublic static final以外でstaticな変数を使わないようにしているので余り問題にであったことはないですが、どんなもんでしょう(もちろんstaticメソッドは使いますが)。

> 「パラメータの上書き」を見ると、関数に再入可能かという話のような気がします。
> static かどうかはおいといて。

ここらへんの話で混乱が生じるのは、Java言語の教科書でスタック領域、ヒープ領域の話とかデータの実体は複数あっても処理(メソッド)の実体はひとつしかないといった低レベルの話が抜け落ちているのが原因なんじゃないかと。

synchronizedメソッドが処理に対してロックをかけているように思えてしまったり、データはint型ひとつしかなくてメソッドが百個あるようなクラスのインスタンス生成をメモリ量を心配して躊躇してしまったり。

C言語のポインタも難しいといわれているけど、スタック領域、ヒープ領域の話がわかっていればすんなりとわかると思うのだけれど。

英-Ran
ベテラン
会議室デビュー日: 2002/06/12
投稿数: 55
投稿日時: 2002-08-02 10:29
> 私は基本的にpublic static final以外でstaticな変数を使わないようにしている

別にpublicに限らないですね。(public | private) static finalに訂正させてください。

あと、staticメソッドだとHotspotとかJITコンパイラの場合にインライン展開してくれるかも……といった話があるかもしれません。ここら辺は詳しくないのでなんですが。
へげもん
ベテラン
会議室デビュー日: 2002/04/14
投稿数: 87
お住まい・勤務地: 埼玉県
投稿日時: 2002-08-02 10:51
 staticメソッドがよく使われる場面としてはFactoryメソッドが上げられますね。そのパッケージで使う様々なクラスのインスタンスを明示的に生成する場合に使います。例としては、Swingの色々なクラスが持っているcreate何とか(...)があります。
 意味的に、あるいは使用する場面として、何らかのクラスに属している必要があるけれども、特にインスタンス変数に依存していない処理の場合、staticメソッドにすることが役に立ちます。
 C/C++では演算子のオーバーロードがあったので、二項演算子(==など)をstaticメソッドとして定義するのが常識でしたが、Javaの場合は役立つ場面がその分減ってるかもしれません。

 それから、「パラメータの上書き」というのは、やはりスタック/ヒープの区別がきちんとついていれば起こらない誤解でしょう。こうしたコンピュータの動作原理に近いところは、できるだけ早い時点で身に付けておかないと、応用が利かなくなりそうで危惧を感じます。

スキルアップ/キャリアアップ(JOB@IT)