• ベストアンサー

不要なstaticメソッドの見分け方。。

実は既に構築されているJavaアプリケーションで異様にstaticを多様しており 要・不要を分けてstaticの意味がないものはstaticを削除する事になりました。 staticの変数だけでも1300以上あり、まずは機械的に振分けたいと思っています。 思いつくのは、アクセス修飾がprivateか、省略されている場合にはローカル 使用と判断してstatic不要と判断出来ると思っているのですが。。。 その他によい見分け方がありましたら、是非、ご教授下さい。 実は、私が作ったものでもなく、突然の依頼でオロオロしているため、 アドバイス等でも何でも頂けると嬉しいです。 どうぞ宜しくお願い致します。

  • Java
  • 回答数5
  • ありがとう数5

質問者が選んだベストアンサー

  • ベストアンサー
  • sasadora
  • ベストアンサー率68% (59/86)
回答No.5

それは大変ですね。始めに作った人はなにも考えずにstaticにしたんでしょうね。 >実は、実際にstaticにしていた為の障害が発生してしまったのです。 >その箇所は修正したのですが、他にこのようなケースがないかを 大変重要なことだと思います。対応するのは非常に大変ですが、対応漏れがあると、また同様の障害が発生するかもしれませんね。 仕様が分からないnsakurakoさんがやるのは、理不尽だと思いますが、そこは、やらなければいけない仕事と割り切って、やることを考えてみました。 1)static宣言している箇所を、漏れなく列挙する  →「修正対象の候補」の列挙 2)列挙した「修正対象の候補」を利用している箇所を全て列挙する  →「利用箇所」の列挙 3)列挙した「利用箇所」のstatic要・不要を仕様から判断する (機械的にできない一番大変なところ) 4)不要なstaticを除去する こんな感じで考えてみました。 大変なのは2)と3)です。 3)は仕様を知らないと判断が難しいと思いますが、2)によって利用されている箇所が“全て”分かっていれば、かなり判断がつきやすいと思います。 そこで2)を楽に行なう方法ですが、 eclipseを使っていれば、ある変数を参照している箇所を簡単に検索することができます。(他のツールでもあるかも知れません) 変数を選んで、[検索]-[参照]-[プロジェクト]とするとプロジェクト内でその変数を参照している箇所が分かります。 これを使うことで、2)の作業は機械的に行なえると思います。 また、nsakurakoさんが、static変数についてよく理解しておく必要があります。No.1の方が指摘するような間違った修正をしてはいけませんからね。 私が思うに、サーブレットを使っていて、定数以外に対しても、意味も分からず、ついstatic変数を使ってしまった輩がいるケースではないでしょうか? 意図的にstatic変数を使っている箇所は0ではないのか?というわけです。 #書いた人が、グローバル変数代わりにstatic変数を使っているようなケースだったらアウト。 であれば、static final以外のstaticをすべて取り除いて、全テストやり直し!っていうのも 最も安心できるやり方の一つだと思いますよ。

nsakurako
質問者

お礼

お礼が遅くなりまして申し訳ありませんでした。 アドバイスは是非、参考にさせていただきます。 やはり、キチンとした調査に必要な工数を別途調整してもらう方向で 進めていきたいと思います。 ただ、アドバイスの通り、現段階までで調べた限りは staticに意図的にしているのは1300件中2,3件だろうと 推測されますので、staticを取り除いて全テストの方が 工数的には早いだろうという気はとてもしています。 丁寧なアドバイスを本当にありがとうございました。

その他の回答 (4)

回答No.4

心中お察し致します。 まずstatic変数だけでも1300以上あるとのことですので、 単純に機械的に要・不要を分けるのを考えると 1. staticメソッドをgrepしてみて、 もし1回も呼ばれていなければ(まずあり得ないと思いますが…) static以前に不要なメソッドです。 2.1.同様にgrepしてみて すべてstatic参照されていなければ 「(どういう設計意図があったかは分かりませんが、今のところ幸か不幸か)staticをとっても構わないメソッド」 です。 3.~static final~な変数、つまり定数 これは定数なので調査対象からは外していいと思います。 とりあえず今、自分が思いつくのはこんなところです。 もし的外れなことを言っていましたら申し訳ありません。 上記以外は他の方も仰っているように、 1つ1つちゃんと見ていくしかないと思います。 これで少しでも減るといいのですが。 がんばって下さい。

nsakurako
質問者

お礼

お礼が遅くなり申し訳ありませんでした。 教えて頂いたアドバイスを参考にさせて頂きます。 丁寧な解説をありがとうございました。

回答No.3

実際に作業しなければならないとなると、余り良い考えは浮かびませんが、考えてみたことを書きます。 > 要・不要を分けてstaticの意味がないものはstaticを削除する事になりました。 これは危険すぎます。 staticじゃまずいものだけ削除するようにした方が、危険は減ると思います。 1300以上ですか、大変ですね。 まず、Stringクラスでfinal宣言されている変数。 これは、放っておいても悪さしないでしょう。 これを除くとどれ位残りますか? 正直、答えきる自信は余りないです。

nsakurako
質問者

お礼

返事が遅くなりまして大変に申し訳ありませんでした。 > まず、Stringクラスでfinal宣言されている変数。 final宣言を差し引いて1300件あります。(T*T;) 製造者さんは悪気があって使用した訳ではないと思いますが、 事実上、全箇所の調査はやはり非現実的ですよね。。とっほ。 > 正直、答えきる自信は余りないです。 いえ、このように回答頂けただけでも本当に心強いです。 ありがとうございました。

  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.2

>申し訳ないです。説明不足でした。 >例に出して頂いたようなクラスの場合にはstatic不要と判断して >下記のように修正するつもりです。 > >class B{ >private int i = 0; ←★privateにする!! >public int Get(){ >return i++; >} >} むやみにstaticをprivateにすると挙動が変わるかもよと言いたかったのですが。 わかっているとは思いますが念のため B b1 = new B(); B b2 = new B(); System.out.println( b1.Get() + "\n"); System.out.println( b2.Get() + "\n"); staticのままだと 0 1 と表示されていたのがprivateにすると 0 0 になります。 変更していいかどうかは、そのメソッドが何をしたいのかを把握しなければ 無理ですね。。。

nsakurako
質問者

お礼

度々、丁寧な回答を本当にありがとうございました。 おっしゃる通りです。 私の勘違いでした。 あやうく、とんでも修正をする所でした。 親切な解説をありがとうございました。 でも、やはり、自分で1300個を判断しないとダメなのですね。。。 うぅぅ。。 

  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.1

つまりstatic宣言が不要なのにstaticをつけている? どういうソースなんだか、よくわかりませんが、 別にstaticだからパフォーマンスが下がるわけではないと思いますし ほっといたのでよいかと思います。 まずいえるのは機械的にstaticの要、不要の判断をするには コンパイラを作る以上に高度な事です。事実上不可能。 >アクセス修飾がprivateか、省略されている場合にはローカル >使用と判断してstatic不要と判断出来る class B{ static int i = 0; public int Get(){ return i++; } } こんなクラスがあってstaticを削除したら大変でしょう。 プログラム全体が動かなく可能性があります。

nsakurako
質問者

お礼

早速の回答をありがとうございました。 > まずいえるのは機械的にstaticの要、不要の判断をするには > コンパイラを作る以上に高度な事です。事実上不可能。 そうなんです。"o(>。<)o" 私もその旨を上司に伝えたのですが納得してもらえず。。。。。 実は、実際にstaticにしていた為の障害が発生してしまったのです。 その箇所は修正したのですが、他にこのようなケースがないかを 調べろとの依頼が仕様も知らない私にやってきました。。とっほ。。 2つ、3つなら、いやいや数十個ならば、自力でソースを追いかけて 自力で判断しても良いのですが、1300以上となるとまさに非現実的で。。 >> アクセス修飾がprivateか、省略されている場合にはローカル >> 使用と判断してstatic不要と判断出来る > こんなクラスがあってstaticを削除したら大変でしょう。 > プログラム全体が動かなく可能性があります。 申し訳ないです。説明不足でした。 例に出して頂いたようなクラスの場合にはstatic不要と判断して 下記のように修正するつもりです。 class B{ private int i = 0; ←★privateにする!! public int Get(){ return i++; } } もし、また、何かありましたら、是非、宜しくお願い致します。 少なくとも非現実的だという意見を頂けて救われる思いでした。 ありがとうございました。

関連するQ&A

  • staticのメリット、デメリット

    こんばんは。 staticについて、だんだんわからなくなってきました・・・。 例えばあるクラスの変数で、 static int i = 10; とあった場合、参照クラスからiの値を見ると、必ず10ですよね? static修飾子がついているメソッドの場合、挙動はどうなるのでしょう? staticなメソッドはインスタンス化しなくても呼び出せる。 つまり、メモリ上に1箇所しか存在しないので、同時にアクセスされた場合(synchronizedしていない場合)はどうなるのかがわかりません・・・。 メソッドには引数が存在し、returnがStringやintなどの場合です。 returnは保証(参照側にとって望む値と言う意味で)されるのでしょうか? インスタンス化をしない事によって、パフォーマンスが向上するのでしょうけれど、いまいちメリットがわかりません・・・。 public、privateにかかわらず、メソッドをstatic修飾するメリットを教えてください。 同時にデメリットもお願いします。 以上、下手くそな文章ですみません・・・。 (^^ゞ

    • ベストアンサー
    • Java
  • staticオブジェクト内の変数

    staticなオブジェクト内のローカル変数は、スレッドセーフだと思うのですが、あっていますでしょうか。 例えば、以下の myfoo変数内の、data変数のようなケースです。 public class foobase() { private static foo myfoo = new foo(); . . } public void foo() { String data = "Hello"; }

    • ベストアンサー
    • Java
  • ◆完全に、privateなメソッドにしたい

    クラスA内に、 privateで、staticなメソッド「hogehoge」を作った時、 完全に、「hogehoge」の中の変数・Inputパラメータ、Outputパラメータだけで処理をさせたいです。 ◆具体例:(こういうのをできないようにしたい) クラスA.h static 変数X static 変数Y static メソッド hogohoge (略) クラスA.cpp メソッド hogohoge (略) { z = 変数X + 変数Y } //---------------------------------- ◆やりたいこと メソッド上のように、変数Xや、変数Yにアクセスできてしまうのを、制限したいのです。  例えば、pragmaとかを書いて、オプションで制限できたりできないでしょうか? 完全に、「hogehoge」の中の変数・Inputパラメータ、Outputパラメータだけで処理をさせたいです。 また、今回はstatic 変数だけを引き合いに出しましたが、  他にも「実はアクセスできちゃうんだよね」というものがあれば、  (例えばdefineとか?) ご教授頂けるとさらに嬉しいです。 .

  • staticのメモリ共有について

    staticについて調べたのですが、その内容があっているのかどうか 間違い・アドバイスなどありましたら是非伺いたいと思います。 よろしくお願い致します。 ------------------------------------------------------------  シェルから起動されるJavaでバッチ処理を行うアプリケーションを  作成していまして、サーバマシンの複数のプロセスから起動されます。  (つまりjavaコマンドが複数回同時に実行されます)  1回の実行の間保持しておきたい値をstaticなクラス変数に格納しています。  そしてそれは、1回の実行の間はずっと同じなのですが、  プロセスごとに異なる値です 。  この時、この1回の実行の間に保持しておきたい"static"な変数は  次のプロセスから実行された時に書き換えられるのか?  という疑問がでたのが始まりです。  マルチスレッドの処理はありません。 ------------------------------------------------------------ 調べたところ、 ■1台で2つ以上のJavaアプリケーションを実行する場合、  それぞれのアプリケーションを個別にjavaコマンドで起動・・・  =>javaコマンド毎に"個別のJVMが"それぞれのプロセス上で動作する。 ■フィールドをstatic指定するとクラス変数となり、  ロードされたクラスごとに"JVM上に"1つしか存在しない変数となる。 ・以上の2点から、staticの変数がメモリ上で共有されるのは  1つのJVM(1プロセス)内での話しであり、他のプロセスから  その値を書き換えられる事はないと考えています。  そして、1プロセス内でのマルチスレッドな処理を行っている場合、  staticな変数の値は注意が必要だけど、  複数プロセスでシングルスレッドな処理を行っている場合、  (性能などの問題上staticにするかどうか良し悪しはあるとしても)  staticな変数の値の不整合について  考慮は不要と考えても宜しいのでしょうか? 経験が浅い為、確信が持てずにいる状況です。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • SAStrutsでServiceのStatic変数

    SAStrutsでServiceのStatic変数の動作で疑問があります。 Eclipse+TomcatでサンプルWebアプリを作成し、以下のサービスをActionから呼び出しています。 これは、Staticなint型の変数に、インスタンスを生成した回数を格納する物です。 public class SampleService{ private static int instanceCnt = 0; public SampleService(){ instanceCnt++; System.out.println(instanceCnt); } } これを何度も呼び出すと、何故かある時突然、出力する数値が1にリセットされるのです。 Static変数はスレッド間で共通で使われているはずなので、これは起こらないはずではないでしょうか? 考えられるとすれば、Tomcatが複数のJavaVMを呼び出して、Webアプリケーションを実行しているのでは、と思うのですが、いまいち確信が持てないのです。 なぜこういう事が起こるのか、詳しい方、教えてもらえないでしょうか。

    • ベストアンサー
    • Java
  • AOPでメソッド内にpointcutを作る方法

    こんにちは。 ログの出力にAOPを使っているのですが、できれば、メソッド内の好きなところにpointcutを設けて、さらにできれば、その際にローカル変数にもアクセスしたいと考えております。 このようなことは可能でしょうか? 今は、privateな空メソッドを作成して、アクセスしたいローカル変数を渡してreflectionで中身を見ています。 上記でも支障はないのですが、本番で空メソッドが無駄に呼ばれているというのも嫌なので。。。 このprivateメソッドの呼び出しを、アノテーションかなんかで、AOPが有効化されているときだけにする、という解決策とかでもOKです。 何卒よろしくお願いいたしますm(_ _)m

    • ベストアンサー
    • Java
  • 【設計思想の質問】staticメソッド、メンバ変数

    【設計思想的な質問】 自分は、結合が弱いソースを好んでおり、 以下の例で言えば、後者のようにするのですが、 このようは書き方は良くないのでしょうか? 新しい現場で、後者の方の書き方をしたら、 「えっ、なんでメンバー変数で宣言してんの? なんで引数で渡してんの?馬鹿じゃないの?」 と、結構、傷つく言葉を受けました。 それはそうとして、 自分としては、「なぜ、やってはいけないのか?」 「自分の設計思想は、設計の方向性としてアリなのか?」などを知りたく、質問させて頂きました。 ご意見、ご鞭撻を宜しくお願い致します。 //----------------------------------------------------------- ★前提1:末端の派生クラスで、このクラスを継承することはない。 ★前提2:提供する処理は様々な処理で使われるユーティリティ機能 ◆案1 class 複雑なクラス //メンバ変数  変数1  変数2  (中略)  変数100 //メソッド private  long 複雑な処理 (void)      (略:色んなメンバー変数が登場するが、       どのメンバと、どのメンバが登場するかは、ソースを追いかけて確認する)  long 自由なタイミングで、色んなメンバ変数の値を書き換えてしまうメソッド (void)       (※上述の「複雑な処理」に登場する変数の取りうる値がフリーダムになる) となるよりも、 //----------------------------------------------------------- ◆案2  static long 複雑な処理 (必要な引数1、必要な引数2、必要な引数3)    (略:登場するINPUT、OUTPUTは、引数に列挙されているものだけ。)  static long 複雑な処理 (必要な引数97、必要な引数98、必要な引数99)    (略:登場するINPUT、OUTPUTは、引数に列挙されているものだけ。)  ※渡す値は、呼び元が意識するため、メンバ変数がどういう状況になっているかは、   メソッドの利用者が把握している。(タイミングも、取りうる値も、認識しやすい) の方が良いという考えなのです。 メンバ変数で書けば、確かに、宣言部、定義部のコーディングで引数のことを書かなくてよいので楽でしょうし、 インタフェースの検討不足で手戻りがあっても、引数の増減で、修正が不要ですし、楽だと思います。 しかし、 「どこからでもアクセスできる変数ばかり」だと、処理の認識も困難だし、バグの温床にもなってしまうことから、私は後者にも、優れている部分はあると考えているのです。 .

  • ネストトップクラス・メンバクラスについて

    現在、SJC-P取得に向け独学でJavaの勉強中です。 ネストクラス・インナークラスについて勉強している最中なのですが、 数冊テキストを読み込んでも、web検索をしても、イマイチよくわからない・・・というのが正直なところです。 どのクラス(アウタークラス/staticインナークラス/非staticインナークラス)の、 どういうメンバ(static/非static/private/final)が、 どのクラスのどういうメンバにアクセス出来るのかが整理しきれません・・・。 わからないなりに、まとめてみたのですが、理解が不十分で、かつ、この下記の通りの理解で正しいのかどうかもわかりません。 (言葉でうまく表現も出来ていない箇所も・・) また理解すべきポイントに不足があるかと思います。 どこが正しく理解出来ているのか・どこがどう間違っているかの指摘及びその内容・理解不足の箇所・よりわかりやすい例の追加や補記など、どうかよろしくお願い致します。 ●staticなインナークラス(=ネストトップクラス)について ・アウタークラスのインスタンスなしに、staticなインナークラスのインスタンスの生成が出来る。 ・staticなインナークラスからはアウタークラスの非staticメンバを直接アクセス出来ない。 (→ただし、staticアウターメンバになら直接アクセス出来る?staticであればprivateでもアクセス可?) ・staticなメソッド内で非staticなインナークラスのオブジェクトが生成出来ない。 ●非staticなインナークラス(=メンバクラス)について ・非staticなインナークラス内にstaticなメンバを持つことは出来ない。 ・アウタークラスのインスタンスを生成してからでないと非staticなインナークラスのインスタンスは生成出来ない。 ・アウタークラスの非staticメンバ及びstaticメンバに直接アクセス出来る。 ●アウタークラス(=外部クラス)について ・アウタークラスのstaticメソッド内で非staticなインナークラスのインスタンスは生成出来ない。 ・非staticインナークラスのメンバ及び、staticなインナークラスのメンバにアクセス出来る。 --------------------------------------------------------- (例)処理はさておき、定義はこんな感じを思い描いております・・ class Outclass{   private int aa;   private static int bb;   private outMethod1();   private static outMethod2();   class NotStaticInner{     private int cc;     //private static int dd;//不可     private inNotStaicMethod1();     //private static inNotStaticMethod2();//不可   }   class StaticInner{     private int ee;     private static int ff;     private inStaticMethod1();     private static inStaticMethod2();   } } 参考テキスト: 『Sun Certified Programmer for Java2 Platform5.0 Exam【310-055】』のChapter11:「ネストクラス・インナークラス」 参考URL: http://wisdom.sakura.ne.jp/programming/java/java46.html

  • クラス修飾子やアクセス修飾子を省略したパッケージ・プライベートは同じフォルダの下層フォルダにも公開するのですか?

     クラス修飾子やアクセス修飾子を省略したパッケージ・プライベートは同じフォルダの下層フォルダにも公開するのですか?  publicなどのクラス修飾子やアクセス修飾子を省略すると、同じフォルダ内のクラスにだけ公開されているパッケージ・プライベートなクラスなど(変数、メソッドとかのメンバを含む)になる、とのことですが、これは同じフォルダだけでなく同じフォルダの下層フォルダにも公開するのですか?  フォルダはパッケージのことです。 Windowsユーザーに分かりやすい言い方で記述しました。  よろしくお願いいたします。

    • ベストアンサー
    • Java
  • 修飾子 private protected

    Java での話です。 自分自身とサブクラスからのみアクセスできる変数は作成することはできないのでしょうか。修飾子 private protected の組み合わせは廃止されたようなのですが。 C++ だと、protectedで良かったと思うのですが、Java では同一パッケージからアクセスできるので戸惑ってしまいました。

    • ベストアンサー
    • Java

専門家に質問してみよう