- PR -

JAVAにおけるstaticメソッド

投稿者投稿内容
北斗のポン
会議室デビュー日: 2003/05/02
投稿数: 17
投稿日時: 2003-05-14 09:55
おはようございます。北斗のポンです。

zaxx_MDさん、うのきちさん、Kensakuさん、本来「JAVAにおけるstaticメソッド」についてのスレッドなのに文法的なところまで教えていただいて大変感謝しています。

無名クラスですか・・・聞いたことはあったのですがどういう技術なのか知らなかったので今回は大変勉強になりました。
あ、ってことは、Windowを閉じる際の「WindowAdapter」はこの技術を使用してたのですね。うーん、使用している技術を知らないなんて・・・技術者として恥ずかしいですね。

ところで、この無名クラスの使用ですが個人的にはコーディングがすっきりするため大変気に入ったので、個人でツールなどを作成する際には積極的に使っていきたいですが、プロジェクトなどのプログラマとしてのレベルが均一でないような場所ではあまり使用しないほうがいいのではないかという印象を受けたのですが(あ、アダプタクラスやJUnitのテストデータの作成は別として)いかがでしょうか?
(えっと、プロジェクトでは「無駄を無くす」よりも「可読性」を優先すると言う考えからなのですが)
taku
ぬし
会議室デビュー日: 2002/11/12
投稿数: 918
お住まい・勤務地: 墨田区→中野区
投稿日時: 2003-05-14 10:38
引用:

ところで、この無名クラスの使用ですが個人的にはコーディングがすっきりするため大変気に入ったので、個人でツールなどを作成する際には積極的に使っていきたいですが、プロジェクトなどのプログラマとしてのレベルが均一でないような場所ではあまり使用しないほうがいいのではないかという印象を受けたのですが(あ、アダプタクラスやJUnitのテストデータの作成は別として)いかがでしょうか?
(えっと、プロジェクトでは「無駄を無くす」よりも「可読性」を優先すると言う考えからなのですが)


 元の趣旨からかなり外れてますが、私見を述べさせていただきます。

 サンのプログラマー試験にも出題される内容なので、
知らないで開発をしているのが問題だと思います。
※プログラマー試験に出題される内容は全て基本です。
Javaを最近(ここ1、2年)はじめた方は、
いきなりサーバーサイドから入るので、
確かに知らない方は多いですね。
基本なんですから、
可読性を優先するあまり使わないというのは本末転倒だと思います。

Javaでの開発はプログラマー認定を必須にすれば良いのかも・・・。
zaxx_MD
大ベテラン
会議室デビュー日: 2003/04/21
投稿数: 204
お住まい・勤務地: 千葉県柏市
投稿日時: 2003-05-14 12:00
引用:

Kensakuさんの書き込み (2003-05-13 22:11) より:
zaxx_MDさんへ

私はうのきちさんの書き方は無駄がなく良いと思います。
この様な書き方が広く普及して欲しいと思っています。


いいえ、広く普及するとかいうものではありません。
皆さんおっしゃっているとおり、Javaの基本文法ですから理解している必要があります。
また、私自身もJVM内で一意のオブジェクトを定義したい場合などに静的初期化子(?)
(static {})を使っていますが、私がそういったトリッキーな処理を書く必要があるのは
フレームワークとして機能を提供する時のみです。

Java書き始めた人が何も考えずに無名クラスを多用したり、
いきなり初期化子を書いてしまうのは何か違うと思います。

素に近い状態からJavaコードを書いている人たちはinnerクラスなどを利用して
インスタンス化のペナルティを少なくする努力とかしてると思いますが、
無名クラス/無名インタフェースは定義と動作が混在するために「非常に嫌い」です。

今の時代でチョットくらいソース(とバイトコード)が短いことに
どれだけのメリットがあるんでしょうか?
無駄が無いほうがいいということならJava使わないのが一番無駄が無いとおもいますけど?
Cとかアセンブラでも書いてたらどうですか?

#J2MEは話が別ですが
HIRO
常連さん
会議室デビュー日: 2003/04/15
投稿数: 20
投稿日時: 2003-05-14 12:55
僕も「特に明確な理由のない限り」判りやすく書くことに賛成です。
初心者でも判るコードで要求が実現できればそれが理想でしょうか。

とはいっても個人のレベルが一様でない現実があるので、

  どこまでが初心者か?
  どこからがトリッキーか?

は、また別の論議を呼んでしまいそうです。
テーマが別に行きそうなのでここでは触れないようにします。
yamasa
ベテラン
会議室デビュー日: 2003/02/15
投稿数: 80
投稿日時: 2003-05-14 13:26
忙しさにかまけてたら、ちょっと話題に乗り遅れちゃってますが…

うのきちさんの2003-05-11 11:50の書き込みへの返信です。

AUtils.getSum(Collection c)メソッドを別のクラスBに適用できるように
拡張する場合、私ならまず以下の方法を考えるでしょうね。

---
get()メソッドを定義した interface X を定義し、A, BはXをimplementsする。
そして、AUtils クラスは XUtils に改名する。
# 場合によっては X を abstract class にしたり、
# B extends A などのように定義するのもありでしょう。
---
この場合、単純なクラス名の変更だけですむので
リファクタリングのサポート機能を持ったエディタなどを用いると
非常に楽に変更が行なえますね。

上記の方法がうまく適用できないような場合、うのきちさんの
挙げられたAccumlationクラスなどは良い案だと思います。
ただ、ちょっと変更を加えて以下のようにするのも
良いのではないでしょうか。
コード:
public abstract class Calculator {
  protected abstract int getValue(Object o);

  public final int getSum(Collection c) {
    int sum = 0;
    for (Iterator it = c.iterator(); it.hasNext(); ) {
      sum += getValue(it.next());
    }
    return sum;
  }
}

public class A {
  private static final Calculator A_CALCULATOR = new Calculator() {
    protected int getValue(Object o) {
      return ((A)o).getHoge();
    }
  };

  public static Calculator calculator() {
    return A_CALCULATOR;
  }

  public int getHoge() {
    ...
  }
}


こうしておくと、あとは単純に AUtils.getSum(...) → A.calculator().getSum(...)
という置換を行なうだけですので、変更も簡単です。
# ただし、クラスごとに計算対象となる属性が決まっていることが条件ですが…


さて、staticメソッドの話に戻して私の意見を述べさせてもらうと、
「オブジェクト指向的ではないなどの理由で無闇にstaticメソッドを
気嫌いすることはない」ということになりますね。
むしろ、使い方次第ではシンプルでわかりやすく、かつ十分に拡張性のある
ロジックを記述することもできます。
まあ、どのようにstaticメソッドを利用するのがよいのかという点については
経験によるところが大きいと思いますが、うまいやり方を「パターン」として
再利用や共有していくことはできると思います。
zaxx_MD
大ベテラン
会議室デビュー日: 2003/04/21
投稿数: 204
お住まい・勤務地: 千葉県柏市
投稿日時: 2003-05-14 14:02
引用:

yamasaさんの書き込み (2003-05-14 13:26) より:
まあ、どのようにstaticメソッドを利用するのがよいのかという点については
経験によるところが大きいと思いますが、うまいやり方を「パターン」として
再利用や共有していくことはできると思います。


私もそう思います。

でもコードについては・・calculatorというモデリングをしたのであれば
コード:

public class ACalc extends Calculator {
protected int getValue(Object o) {
return ((A)o).getHoge();
}
}

public class A {
...
public int getHoge() {
...
}
}

public class ATestCase extends TestCase {
public ATestCase(String name) {
super(name);
}

public void testCtg() throws Exception {
A aObj = new A(1);
...
AList aList = new AList();
ACalc calc = new ACalc();
assertTrue("calc.getSum(aList)", 0 < calc.getSum(aList));
}
}


これじゃダメなんですか?
インスタンス化の省略?

[ メッセージ編集済み 編集者: zaxx_MD 編集日時 2003-05-14 14:08 ]
うのきち
ベテラン
会議室デビュー日: 2003/02/17
投稿数: 55
投稿日時: 2003-05-14 15:15
そうですね。インタフェースが使えるのであれば、それを使うのが一番簡単。
でも、元コードが、いつも自分の支配下にあるわけではないので、そういう場合は、私が示したアダプタパターンとか、yamasaさんの示したテンプレートメソッドパターンとかを使うわけです。こういったstaticメソッドによる解以外もあるということで。
うのきち
ベテラン
会議室デビュー日: 2003/02/17
投稿数: 55
投稿日時: 2003-05-14 15:26
引用:

ところで、この無名クラスの使用ですが個人的にはコーディングがすっきりするため大変気に入ったので、個人でツールなどを作成する際には積極的に使っていきたいですが、プロジェクトなどのプログラマとしてのレベルが均一でないような場所ではあまり使用しないほうがいいのではないかという印象を受けたのですが(あ、アダプタクラスやJUnitのテストデータの作成は別として)いかがでしょうか?



エンジニアリングの観点からは、それは、まったくその通りです。
でも、staticを「下手に乱用する」のは三流プログラマにも出来ますが「上手に制限を持って使う=クラスの拡張性、独立性を落とさずに使う」のは、一流のアーキテクトにしかできないというのが、私の結論です。

なので、私のような凡人は、デザインパターンで挙げられているような場面(主に生成パターン)でしか、staticを使わないようにしていますし、経験の少ないプログラマの方には「staticは出来る限り使わないようにしてください」とお願いします。

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