• 締切済み

staticメソッドの長所短所

初めまして。 c言語からjavaの勉強を始めたものです。 javaには共通ライブラリをstaticなメソッド(この言い方に慣れない)で作ることが多いようですが、なぜですか? 私の認識は、 staticはメモリの共有領域に確保され誰からも参照できる。 よって、メモリの効率的な確保が出来る。 でも、メソッドを共有領域に持つと各ユーザからそのメソッドが呼ばれたときに同じメモリをさすメソッドが使用される。 つまり、違うユーザがパラメタ違いで同じメソッドを使用すると、処理の途中でパラメタが書き換わってしまう可能性があるかと思います。 これって問題ないのでしょうか? Sumple public static boolean check(String str){ if(str==null){ return false; } int num = Integer.parseInt(str); if(num < 0){ retrun true; } else { retrun false; } } こんなメソッドがあり、パラメタが「2」の人と「-10」の人が同時にアクセスすると結果が変わりそうな気がします。 よろしくお願いします。

  • Java
  • 回答数3
  • ありがとう数8

みんなの回答

  • symgt
  • ベストアンサー率56% (68/120)
回答No.3

> javaには共通ライブラリをstaticなメソッド(この言い方に慣れない)で作ることが > 多いようですが、なぜですか? 通常、クラスのメソッドを使用するにはそのクラスの インスタンスを生成しなければなりません。 しかし、共通ライブラリのように使用頻度の高いメソッドの場合、 そのつどインスタンスを生成していては効率が悪いのため staticメソッドにすることが多いようです。

  • UKY
  • ベストアンサー率50% (604/1207)
回答No.2

> こんなメソッドがあり、パラメタが「2」の人と「-10」の人が同時にアクセスすると結果が変わりそうな気がします 理由の前に答えを言いますが、そんなことはありません。 > staticはメモリの共有領域に確保され誰からも参照できる。 staticにするとひとつのメモリを共有するというのは、フィールドの話です。 例えば、次の例では、SetとPow5の二つのメソッドに同時にアクセスするとうまくいかなくなります。 class Sample {      static int value;      public static void Set(int v) {     value = v;   }      public static int Pow5() {     return value * value * value * value * value;   }    } Pow5メソッドが掛け算を行っている間に、Setメソッドがvalueの値を変えてしまうと、うまくいきません。 例えば計算の途中でvalueが2から5に変わると、Pow5が返す計算結果は 2 * 2 * 5 * 5 * 5 のようになってしまいます。 (もちろん、このようなことが起こらないようにするための対策法もJavaには用意されています。) しかし、メソッドは話は別です。たとえメソッドがstaticであったとしても、ローカル変数までもがstaticになってしまうことはありません。 つまり、複数のスレッドが同時に同じstaticメソッドを呼び出したとしても、ローカル変数はそれぞれのスレッドで別々に用意されるのです。(C言語で言う所の「動的変数」です。Javaには、Cで言う「静的変数」はありません。) フィールドやメソッドをstaticにするということは、それらをクラスのインスタンスと関連付けないということです。(C言語で使うstaticとはちょっと意味合いが違います。) メソッドをstaticにする理由も、まさにここにあります。そのメソッドがインスタンスとつながりを持つかどうかによってstaticにするかどうかを決めるのです。 余談ですが、 if(num < 0){ retrun true; } else { retrun false; } と5行使って書くよりも1行で return num < 0; と書いたほうがビシッとしていてスマートですよ。

  • liar_adan
  • ベストアンサー率48% (730/1515)
回答No.1

>こんなメソッドがあり、パラメタが「2」の人と「-10」の人が同時にアクセスすると結果が変わりそうな気がします。 そういうことはありません。 メソッド内で宣言された変数は、 そのメソッドを実行するときだけの変数です。 問題になるのは以下のような場合です。 class A{ static int value; public int changeValue(x){ int tmp = value; value = x; return tmp; } } つまり、staticメソッド自体は問題ないのですが、 static変数をメソッド内であれやこれやする処理で、 複数のスレッドを使うと結果が変になる場合があります。 そのため、複数のスレッドから使われるメソッドはsynchronizedをつけます。 共通ライブラリをstaticで作る理由は…、 たとえば、java.lang.Integerにいくつかstaticメソッドがありますが、 これらは論理的には、Integerクラスの中になくてもいいものです。 しかし、「関係あるメソッドだから、入れてしまえ」 ということで、Integerクラスに入っています。 本来、Javaではstaticメソッドはあまり推奨されるものではありません。 staticメソッドは、オブジェクト指向の作法から言うと、 やや問題があるものだからです。 (このへんのことを話すとものすごく長くなるので、略します) staticメソッドが多すぎるようだったら、 あまりオブジェクト指向的でないライブラリかもしれません。

関連するQ&A

  • Javaでメソッドから強制脱出する方法は?

    Javaでメソッドから強制脱出する方法はどのようにすればよいでしょうか? 例えばコードとしてはこんなつくりなのですが・・・ private・・・ if (count == false) { } といったようにif文の条件に当てはまったときこのメソッドでの処理をしたくないわけですがどうすればよいでしょうか?

    • ベストアンサー
    • Java
  • Javaで可変長メソッドから別の可変長を呼ぶには?

    Javaで以下のような二つの可変長メソッドがあるとして func1からfunc2を呼び出すにはどういう風にかけばいいのでしょうか? 可変長パラメーターを持つメソッドの書き方はググるといっぱい見つかるのですが 可変長から可変長を呼び出す方法がわかりませんでした。 public static String func1(Object...args){ } public static String func2(Object...args){ } ちなみにどちらも自作のメソッドで 処理をパーツ化するために別々のメソッドに分けたいです。 (それぞれ単独で使うこともあるので) 以上よろしくお願いいたします。

    • ベストアンサー
    • Java
  • getter、setterメソッドを活用したいです

    Javaのgetter、setterメソッドをうまく使って、下記のコードを実行しようとしたのですが。 ---------------- package javatest; public class Jidosha { private int num; private double gas; public void setNum(int num) { this.num = num; } public void setGas(double gas) { this.gas = gas; } public int getNum() { return num; } public double getGas() { return gas; } public static void main(String args[]) { System.out.println("この車のナンバーは" + num + "です。"); System.out.println("この車のガソリンが入る最大量は " + gas + "です。"); } } ---------------- Eclipse上では「System.out.println・・・」のところで「非 static フィールド gas を static 参照できません」といったエラーが出てきまして。 getter、setterメソッドをうまく活用して「この車のナンバーは××××です」「この車のガソリンが入る最大量は〇〇〇〇です。」という文を出力するには、どう書けばよいでしょうか。 よろしくお願い致します。 ※OKWAVEより補足:「Webシステム開発」についての質問です。

    • ベストアンサー
    • Java
  • javaプログラムについて

    mainメソッド内の指定された部分の処理を、 別のメソッドに分けてください。 mainメソッド内から作成した別メソッドを呼び出して 実行できるようにしてください。 ※分ける前と分けた後で処理結果が変わらないこと (入力された文字が"A"の場合true, それ以外の場合falseを返すように) */ class MethodAdd1{ public static void main(String[] args){ /* // ★ここから if("A".equals(args[0])){ judge = true; }else{ judge = false; } // ★ここまで */ boolean judge; if("A".equals(args[0])){ System.out.println("true"); }else{ System.out.println("false"); } } /* **戻り値:boolean **引数:String */ //ここにメソッドを作成 public static boolean equals(String a){ String str="A"; if("A".equals(str)){ return true; }else{ return false; } } } これで一応trueかfalseと表示されるのですが、合っているのか分かりません。 お時間のある方で、手直しをして頂ける方お願い致します。

  • 【Java】親クラスでMainメソッドの出力

    Javaについてです。 コマンドライン引数を複数渡し、数値の判定をtry/catchで行う。 catchメソッドには「stringFlg = true;」のみ。 渡ってきた値が数字のみの場合は、数値*数値の文字数を出力し、 数字のみでない場合は文字列を逆から1文字ずつ出力する。 上記のプログラムを下記のように変更したいです。 Testクラスで別パッケージのTest2クラスを継承し、Test2のLogメソッドを呼び出す。 引数で渡ってきた値をMainメソッドでコンソールに出力していたところを Logメソッドでコンソールに出力する。 Mainメソッドを呼びだそうとするとコンパイルエラーが起きる上に、 Mainメソッド内でLogメソッドをどこで呼び出せばいいのかイマイチ分かりません。 教えて下さい。 現時点のソースコードです。 package Test; import Test2.Test2; public class Test extends Test2 { public static void main(String[] args) { Test2 Log = new Test2(); boolean stringFlg = false; for (String arg : args) { try { int num = Integer.parseInt(arg); int nums = num * arg.length(); Log.Log(); stringFlg = false; } catch (NumberFormatException e) { stringFlg = true; }if(stringFlg){ char[] chars = arg.toCharArray(); for (int i = chars.length - 1; i >= 0; i--){ char str = chars[i]; Log.Log(); } } } } } package Test2; import Test.Test; public class Test2 { public void Log() { Test2 test2 = new Test(); System.out.println(test.main(args[0])); //コンパイルエラー } }

  • 静的変数と静的メソッドの使い方について

    独習JAVAにてJAVAを学習しています。「コマンドライン引数を受け取り、それをスペイン語表記に変換して表示するアプリケーションを作成しなさい。例えば、OneはUno、・・・、FiveはCincoになります。静的メソッドを使って実現しなさい」という問題で躓きました。以下、私が作成したプログラムです。 class Language { static String st[] = new String[5]; //静的初期化ブロックは実行しない。 //コマンドライン引数を受け取るmainメソッドが使えないため //静的メソッド static String translation(){ for(int i = 0; i < st.length; i++) { if(st[i] == "One") return st[i] = "Uno"; if(st[i] == "Two") return st[i] = "Dos"; if(st[i] == "Three") return st[i] = "Tres"; if(st[i] == "Four") return st[i] = "Quatro"; if(st[i] == "Five") return st[i] = "Cinco"; } } //21行目 } class StaticalMethodPractice { public static void main(String args[]) { //mainメソッドが登場したので、静的変数を初期化する for(int i = 0; i < Language.st.length; i++) Language.st[i] = args[i]; //静的メソッドを実行 System.out.println(Language.translation()); } } このプログラムに対して、21行目return文が指定されていませんというエラーメッセージが出てくるのですが、そもそもreturnの使い方もよく分からないので右往左往している状況です。低級な質問かもしれませんが、よかったらアドバイスの方よろしくお願いします。

  • equals()メソッドの継承について

    ある本に ーーーーーーーーーーーーーーーーーーーーー class Car { protected int num; protected double gas; public Car() { num = 0; gas = 0.0; System.out.println("車を作成しました。"); } } class Sample8 { public static void main(String[] args) { Car car1 = new Car(); Car car2 = new Car(); Car car3; car3 = car1; boolean bl1 = car1.equals(car2); boolean bl2 = car1.equals(car3); System.out.println("car1とcar2が同じか調べたところ" + bl1 + "でした。"); System.out.println("car1とcar3が同じか調べたところ" + bl2 + "でした。"); } } JavaのクラスはすべてObjectクラスのメンバを継承していますので、equals()メソッドを記述しなくても、このメソッドを呼び出すことが出来るわけです。 ----------------------------------------- JavaのクラスはすべてObjectクラスのメンバを継承していますので、equals()メソッドを記述しなくても、このメソッドを呼び出すことが出来る    についてですが、 逆から言えば他の言語の場合は本来クラスの宣言の辺りにでもequals()メソッドを記述する必要があるという意味なんでしょうか?

    • ベストアンサー
    • Java
  • formatメソッドについて

    こんばんは。皆様、今回も宜しくお願い致します<(_ _)> 例えば1という値を渡したら、「001」というように表示させてたくて、下記のようなソースを作成してみました。 import java.text.*; class Main{ public static void main(String args[]){ DecimalFormat fmt = new DecimalFormt(); fmt.setMaximumIntegerDigits(3); fmt.setMinimumIntegerDigits(3); String str = fmt.format(1); System.out.println(str); } } これを実行すると「001」というように、私の希望通りに表示されます。 でも String str = fmt.format(1); の部分を String str = fmt.format("1"); と変更すると下記のエラーが出力されます。 Exception in thread "main" java.lang.IllegalArgumentException: Cannot format giv en Object as a Number at java.text.NumberFormat.format(NumberFormat.java:219) at java.text.Format.format(Format.java:133) at Main.main(Main.java:8) そこでJavaのリファレンスを見て、疑問を持ちました。 リファレンスにはFormatクラスのformatメソッドの引数はオブジェクトになってます。 ということはむしろエラーになったほうが正しくて(String=オブジェクトだから)、普通に実行できたほうがおかしいんじゃないか?(数値=基本型だから)と思ったのです。 どうしてエラーがでるのか、どうしてオブジェクトを渡していないのに普通に実行できるのか、わかる方がいらっしゃったら教えて下さい。 宜しくお願い致します<(_ _)>

    • ベストアンサー
    • Java
  • Scanner と BufferedReader

    javaでキーボードからの入力を格納するやつがあって、 Scanner と BufferedReaderのやり方がありますが、これはどう違うのでしょうか? それとも全く同じでしょうか? たとえば、 ■一つ目 import java.io.*; class Sample3{ public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("文字列を入力してください"); String str1=br.readLine(); System.out.println("検索文字を入力してください"); String str2=br.readLine(); char ch=str2.charAt(0); int num=str1.indexOf(ch); if(num !=-1) System.out.println(str1+"の"+(num+1)+"番目に「"+ch+"」が見つかりました"); else System.out.println(str1+"に「"+ch+"」はありません"); } } ■二つ目 import java.util.Scanner; class Sample4{ public static void main(String[] args){ Scanner stdIn=new Scanner(System.in); System.out.println("文字列を入力してください"); String str1=stdIn.nextLine(); System.out.println("検索文字を入力してください"); String str2=stdIn.nextLine(); char ch=str2.charAt(0); int num=str1.indexOf(ch); if(num !=-1) System.out.println(str1+"の"+(num+1)+"番目に「"+ch+"」が見つかりました"); else System.out.println(str1+"に「"+ch+"」はありません"); } } これら2つは全く同じ実行結果が得られると思うのですが、 Scanner と BufferedReader の使い分けるべき場合などあるのでしょうか?

    • ベストアンサー
    • Java
  • 文字列の比較

    いつも参考にさせて頂いています。 基本的なことなのですが、宜しくお願いします。 たとえば文字列"str"の空チェックをするとします。 -------------------以下参考ソース String str = "test"; 1. public static String isBlank(String str) { if(str == null || str.equals("")) { return true; } return false; } 2. public static String isBlank(String str) { if(str == null || str.length = 0) { return true; } return false; } ■1と2の違いって何かありますでしょうか? ■空チェックなら1と2のどちらを使うべきでしょうか? 以上宜しくお願いします。

    • ベストアンサー
    • Java

専門家に質問してみよう