StringBufferからStringへキャストする方法としてどちらを用いるのが一般的なのでしょうか
StringBuffer sb
として
public String ***(***)メソッドの最後に

1. return sb.toString()とする
2. return new String(sb)とする

私は1を使っていたのですが、
Javaの規約だか処理能力が良い方法だかに
厳しい人が2を使っていたので少し戸惑う程度ですが…
回答よろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

toString()メソッドは全てのClassのスーパクラスであるObjectクラスのメソッドです。


その他のクラスのtoString()メソッドは、これをオーバライドしたに過ぎません。
toString()メソッドの用途はそのオブジェクトを視覚的にあらわすときに利用します。オブジェクトのダンプイメージです。
今回はStringBufferクラスのtoString()メソッドのためダンプイメージがStringそのもののため問題ありませんが、
「Stringにキャストする」と明示的に処理するには2を使用するのが正解と思います。
格クラスのtoString()メソッドはDEBUGで画面やファイルに出力するときに使用すると考えたほうが賢明と思います。
    • good
    • 1

参考URLに、この問題についての議論が行われています



そこでも議論されているように正しいのは2の方だと思います。
未だにJava自身のソースや「プログラミング言語Java 第3版」の中でも、sb.toString()が
例として上がっているようですが。

ちなみに、個人的に1を使っていました。
1つ勉強になりました

参考URL:http://java-house.jp/ml/archive/j-h-b/012934.html
    • good
    • 1
この回答へのお礼

まとめてのお礼になり申し訳ないです。

皆様の意見を私なりに解釈してこうなりました。

・String toString()はObjectメソッドを継承しているクラスなので戻り値がStringである事はJavaをそこそこ触れれば誰もがわかる
・str = strinBuffer.toString();がたまたまStringへキャストした値を返していた。
・newを使用するよりも動作的にも早かった。
と言う理由で(1)が浸透してしまった(orしつつあった)

しかし、strinBuffer.toString();が将来#StringBuffer:6542154等ということになりかねないし、StringBufferクラスを継承させて使おうものならtoString()オーバーライドされればTheEnd…
その点、new String(StringBuffer)ならば確実にキャストされる。
ですので(2)を使用するのが正しい…

atonさん、web5さん、bo-kenさん、spoonyさん、本当にありがとうございました。

お礼日時:2002/03/08 14:07

StringBufferソースを見ると、


return new String(sb);
のようにtoString()がオーバーライドされていたと思います。

厳しい人が2を使っていたというのは、
その方が正確・・・というか、理解しやすいからでしょう。
1を使う人は、StringBufferのtoString()が、
オーバーライドされているということを知らない人が多いと思います。
ちなみに、私も2の書き方をします。

また、バイトコードのサイズを比較されていた方もおられますが、
現在はHDDもメモリも安価になり、大量に積んでいるマシンが多いため、
あまり気にすることはないように思います。

sb.toString()を使ってtoString()内部で何がされているかわからないよりも、
new String(sb)として、Stringオブジェクトを返しているという明示的なわかりやすさを得る方がいいと思います。
    • good
    • 0

以下の2つのクラスを作って簡単に実験してみました。



==========
class STest1
{
public static void main(String[] args)
{
System.out.println(getString(args[0]));
}

static String getString(String str)
{
StringBuffer sb = new StringBuffer(str);
return sb.toString();
}
}
==========
class STest2
{
public static void main(String[] args)
{
System.out.println(getString(args[0]));
}

static String getString(String str)
{
StringBuffer sb = new StringBuffer(str);
return new String(sb);
}
}
==========

バイトコードのサイズは,STest1.classが605バイト,STest2.classが627バイト。これをそれぞれ javap -c してみると,当然ですが違いはgetString()メソッドの最後の方だけで,STest1のほうが,

8 astore_1
9 aload_1
10 invokevirtual #7 <Method java.lang.String toString()>
13 areturn

であるのに対し,STest2のほうは,

8 astore_1
9 new #7 <Class java.lang.String>
12 dup
13 aload_1
14 invokespecial #8 <Method java.lang.String(java.lang.StringBuffer)>
17 areturn

となっていました。これを見るかぎり,toString()を使ったほうが効率が良く,new String() を使うメリットは何も考えられないのですが…。
    • good
    • 1

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QJavaのString、StringBuffer、Charの中でメモリ

JavaのString、StringBuffer、Charの中でメモリの使用が一番良いものは?
Java初心者です。
現在JavaMEのMIDP(2.0)で辞書アプリケーションを作成しています。
携帯電話のメモリが小さいことから不向きではあると思っていますが、できるだけ多くの単語と説明を登録していようとしています。
基本的な文法は通常のJavaと同じだと思います。

大まかな構造は不要部分を省きますと、
-----
class Dictionary extend Canvas(){
 int i,j,start=0,end=0,x=1;
 private static Font fontL=Font.getFont(Font.FACE_MONOSPACE,Font.STYLE_PLAIN,Font.SIZE_LARGE);

 void paint(Graphics g){
  //getsetsumei(x)で単語の意味・説明をString型で受け取っています。
  //substringで一文字ずつ増やしながら文字の横幅をgetWidthで受け取り、
  //描画画面横幅の最大値240を越えないように部分文字列で表示しています。
  //文字の続きは文字サイズの縦幅をfontL.getHeight()で取得し、
  //改行のような形で続けて表示します。
  //また描画画面縦幅の最大領域getHeight()を越えて表示しないために
  //i行目までに描画した文字列の縦幅の総和がこれを越えないようにすることで、
  //無駄な描画をしないようにしています。

  for(i=1;i!=0 && i*fontL.getHeight()<getHeight()-130;i++){//画面縦幅の描画範囲の判定
   while(fontL.stringWidth(getsetsumei(x).substring(start,end+1))<240){//画面横幅の描画範囲の判定
    end++;//横幅に達するまで文字数を増やす
    if(end==getsetsumei(x).length()){//表示すべき文字列の取得が終わった
     g.drawSubstring(getsetsumei(x),start,end-start,0,130+x,Graphics.TOP|Graphics.LEFT);
     i=-1;//終了条件のi!=0を満たさなくするため
     break;
    }
   }
   //描画すべき文字列の一部をSubstringで描画
   g.drawSubstring(getsetsumei(x),start,end-start,0,130+y,Graphics.TOP|Graphics.LEFT);
   start=end;//次の行の描画すべき部分文字列の開始位置を指定
   y+=fontL.getHeight()+1;//改行のためのy座標の移動
  }
 }

 String getsetsumei(int DicNum){
  switch(DicNum){
  case 0:return " ";//説明無し
  case 1:return "辞典,辞書,字引";//Dictionaryの意味、説明
  }
 }
}
-----
となっています。
実際は単語の意味をString型で返すgetsetsumeiの引数xの値を変化させて単語に合わせて意味を取得しようとしています。
改行するプログラムのためにgetsetsumei関数は何度も呼ばれることになるので、できるだけメモリを使用せず、高速にしたいと思っています。
色々調べたところStringは非可変文字列であるとのことでした。
これは説明内容が変更されるたびに別のメモリを確保するということでしょうか?
それとも同じメモリに新しい説明が上書きされるのでしょうか?その場合、StringではなくStringBufferを使用すべき、もしくはchar配列を使用すべきでしょうか?
どなたかご教授願います。

JavaのString、StringBuffer、Charの中でメモリの使用が一番良いものは?
Java初心者です。
現在JavaMEのMIDP(2.0)で辞書アプリケーションを作成しています。
携帯電話のメモリが小さいことから不向きではあると思っていますが、できるだけ多くの単語と説明を登録していようとしています。
基本的な文法は通常のJavaと同じだと思います。

大まかな構造は不要部分を省きますと、
-----
class Dictionary extend Canvas(){
 int i,j,start=0,end=0,x=1;
 private static Font fontL=Font.getFont(Font.FACE_MONOS...続きを読む

Aベストアンサー

「String型のオブジェクトが不変」ということの意味を勘違いされていると思います。オブジェクトの中身とオブジェクトへの参照を区別してください。不変なのはオブジェクトの中身のほう。
下記のようなコードで変数setsumeiはString型オブジェクトへの参照を保持しているだけなので、実行しても変数setsumeiが保存されているメモリが毎回確保されるなどということはなく、同じ場所が上書きされます。

String setsumei;
setsumei=getSetsumei(1);
setsumei=getSetsumei(2);
setsumei=getSetsumei(3);

QInteger.parseInt()について public static void main(String[] args) { int a =

初歩的な質問だと思うのですが、、、

public class TestTree {

public static void main(String[] args) {

int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);

GreatTree myTree = new GreatTree(a, b);
myTree.makeTree();
myTree.makeGround();
}

}

というプログラムについて、Integer.parseInt()はどういう意味を持つのかがわかりません。ただ適当につけた名前だとは思えないです。教えてもらえたら幸いです。お願いします。

Aベストアンサー

> argsで入力されたものは例え数字でも文字列として扱われているから、それをintにしている。ということですよね?

引数として (String[] args) と設定されていますので、
おっしゃるとおり 引数 args[]配列に入っているものは、文字列です。

ポイントは、 「String[]」でしょうか。。

QtoStringメソッドについて

java言語超初心者です。以下のコードを入力しました。
class MyCls1 {
String name;
int count;

public void look() {
System.out.println("名前" + name + "個数" + count);
}
}

class MyCls2 {
String name;
int count;

public void look() {
System.out.println("なまえ" + name + "こすう" + count);
}

public String toString() {
String str = "MyCls2:name = " + name + "count=" + count;
return str;
}
}

public class JaCls06 {
public static void main(String args[]) {
MyCls1 bbb = new MyCls1();
bbb.name = "AAA";
bbb.count = 111;
bbb.look();
System.out.println(bbb);

MyCls2 dd = new MyCls2();
dd.name = "BBB";
dd.count = 2222;
dd.look();
System.out.println(dd);

String ee;
ee = dd.toString();
System.out.println(ee);
}
}
実行結果が
名前AAA個数111
MyCls1@19821f
なまえBBBこすう2222
MyCls2:name = BBBcount=2222
MyCls2:name = BBBcount=2222
なんですが、2行目以降の結果がどの行を反映して出てきたのかが全くわかりません。どうか、教えてください。初歩的な質問で申し訳ないです。

java言語超初心者です。以下のコードを入力しました。
class MyCls1 {
String name;
int count;

public void look() {
System.out.println("名前" + name + "個数" + count);
}
}

class MyCls2 {
String name;
int count;

public void look() {
System.out.println("なまえ" + name + "こすう" + count);
}

public String toString() {
String str = "MyCls2:name = " + name + "count=" + count;
return str;
}
}

public class JaCls06 {
public stati...続きを読む

Aベストアンサー

>これは今勉強に使っている本の
>練習問題です。

そんな本は、処分することを個人的にはお勧めします。
まずは、次に上げる統合開発環境Eclipseの解説書のどちらか(または両方)を
入手することを強くお勧めします。
これらの解説書には、ほぼ全ての機能が包括的に解説されていますので、
実用上も辞書的に活用できて非常に有益です。


Eclipse3.3 完全攻略 宮本 信二
¥ 2,940
http://www.amazon.co.jp/Eclipse3-3-%E5%AE%8C%E5%85%A8%E6%94%BB%E7%95%A5-%E5%AE%AE%E6%9C%AC-%E4%BF%A1%E4%BA%8C/dp/4797347074/ref=sr_1_2?ie=UTF8&s=books&qid=1213595941&sr=1-2

開発のプロが教える標準Eclipse 3.3完全解説 (デベロッパー・ツール・シリーズ) 鈴村 幸太郎 ほか
¥ 2,940
http://www.amazon.co.jp/%E9%96%8B%E7%99%BA%E3%81%AE%E3%83%97%E3%83%AD%E3%81%8C%E6%95%99%E3%81%88%E3%82%8B%E6%A8%99%E6%BA%96Eclipse-3-3%E5%AE%8C%E5%85%A8%E8%A7%A3%E8%AA%AC-%E3%83%87%E3%83%99%E3%83%AD%E3%83%83%E3%83%91%E3%83%BC%E3%83%BB%E3%83%84%E3%83%BC%E3%83%AB%E3%83%BB%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E9%88%B4%E6%9D%91-%E5%B9%B8%E5%A4%AA%E9%83%8E/dp/475615087X/ref=pd_bxgy_b_img_b



それと、Javaの解説書としては、次のリンク内に示したものをお勧めします。
http://okwave.jp/qa3929030.html


Javaの入門書には、全くレベルの低いものが沢山あります。
インターネット時代ですから、簡単な入門レベルの情報は、WEB上に散在しており、
個人的にはそれで十分かと思います。
せっかくお金をつぎ込むのなら、長い将来にわたって役に立ちそうな、本格的な
書籍を購入するべきだと考えます。

>これは今勉強に使っている本の
>練習問題です。

そんな本は、処分することを個人的にはお勧めします。
まずは、次に上げる統合開発環境Eclipseの解説書のどちらか(または両方)を
入手することを強くお勧めします。
これらの解説書には、ほぼ全ての機能が包括的に解説されていますので、
実用上も辞書的に活用できて非常に有益です。


Eclipse3.3 完全攻略 宮本 信二
¥ 2,940
http://www.amazon.co.jp/Eclipse3-3-%E5%AE%8C%E5%85%A8%E6%94%BB%E7%95%A5-%E5%AE%AE%E6%9C%AC-%E4%BF%A1%E4%BA%8...続きを読む

Qpublic static void main(String args

public static void main(String args[]) {

public static void main(String[] args) {
は何が違います?

Aベストアンサー

何も違いません。

javaでは配列を宣言する時に、型の後ろに[]をつけても
変数名の後ろに[]を付けてもどちらでもいいことになっています。

Qpublic static void main (String args[])

基本すぎて申し訳ありませんが、
public static void main (String args[])とはどういう意味を持っていますか?
教えてください。。

Aベストアンサー

staticとかの意味はNo1の方の説明以外にありません。

mainは最初に実行されるメソッドという説明がされますので、「クラスを実行する時の引数とは?」と引っかかっているのかもしれませんね。
これはコマンドライン引数と呼ばれます。

たとえば、次のプログラム

public class ArgsTest{
  public static void main(String[] args){
    System.out.println(args.length);
    for(int i = 0 ; i < args.length ; i++){
      System.out.println(args[i]);
    }
  }
}

これを
>java ArgsTest abcde fghij(エンター)
として実行するとabcdeとfghijが引数となります。

ちなみに、mainはpublicでstaticなメソッドなので、
public class ArgsTest2{
  public static void main(String args[]){
    tamesi();
  }
  void tamesi(){
    String[] test = {"abcde","fghij"};
    ArgsTest.main(test);
  }
}
のように、外部のクラスからクラス名.mainで呼び出せます。(この2つのプログラムは、私が悩んだ時に試しにつくったものです)

ちなみにargsはarguments(=引数)の略で、mainの引数として、よく使われます。
argvのほうはargument valueの略です。C言語を使っていた人の中にはargvを使う人がいるかもしれません。

staticとかの意味はNo1の方の説明以外にありません。

mainは最初に実行されるメソッドという説明がされますので、「クラスを実行する時の引数とは?」と引っかかっているのかもしれませんね。
これはコマンドライン引数と呼ばれます。

たとえば、次のプログラム

public class ArgsTest{
  public static void main(String[] args){
    System.out.println(args.length);
    for(int i = 0 ; i < args.length ; i++){
      System.out.println(args[i]);
    }
  }
}

...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報