• 締切済み

Java Stringに関して

   お世話になります。  SJC-Pの学習をしているのですが、Stringに関して、とある教科書に  以下のように記述されていましたが意味がわかりません。  わかりやすく教えていただけたらと思います。  教科書の文章(以下)   同じリテラル文字列に再び出会った場合、コンパイラは既にプール内  に格納されている文字列を使います。(3つ以上の参照変数が同じ  文字列を参照する可能性があるため、この処理はスレッドセーフ  ではない。)  上記文章の( ) で囲まれた部分の意味がまったくわかりません。  よろしくお願いします。

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

みんなの回答

回答No.3

#1です。あれからいろいろと自分でも考えてみたんですが,よく分からなかったです。(もしかしたら、#1のソースも全然、関係ないかも。) 「スレッドセーフ」という言葉は、SJC-Pの出題範囲内では他でもコレクションの項目などで出てきたりしますが、それは該当するコレクションクラス内のメソッドがsynchronizedになっているということであって、Stringの等価・不等価とはあまり関連性がないように思われます。 恐らく、その教科書の記述の近くに、該当する部分を実装したソースが載っているのではないかと思い、似たようなソースを提示してみたのですが、質問者さんが関係ないとお思いでしたら、全く的外れな回答だったと思います。

  • hejaheja
  • ベストアンサー率0% (0/0)
回答No.2

複数ある参照先のいずれかで データの書き換え等が発生した場合に 想定外のデータが入ってしまう String hoge1 = "aaaa"; String hoge2 = "aaaa"; String hoge3 = "aaaa"; hoge1~3の "aaaa" は1箇所のアドレスに存在しているため たとえばhoge1が"bbbb"に書き換えられた場合 hoge2、hoge3の値まで書き換わってしまい hoge2、hoge3では想定外のデータが取得できてしまう。 つまり”スレッドセーフではない”ってこと。たぶん。

回答No.1

/** 「スレッドセーフ」については、マルチスレッドの所に詳しく書かれていると思うので、そちらを勉強するまでいったん棚上げしておくのも、効率的な勉強法の一つ。 */ public class Safe{  public static void main(String[] args){   // 暗黙的にnewするのは、最初のみ。   String str_1    = "1つ目";   String str_1_1   = "1つ目"; // ヒープ内の同じオブジェクトを代用。   String str_1_1_1  = "1つ目"; // ヒープ内の同じオブジェクトを代用。   String str_1_1_1_1 = "1つ目"; // ヒープ内の同じオブジェクトを代用。   // 同じオブジェクトかどうかの比較の為に、==を使用。   // equalsメソッドは、文字列の比較の時に使う。   if(str_1 == str_1_1 || str_1 == str_1_1_1             || str_1 == str_1_1_1_1){    System.out.println("3つ以上の参照変数が、同じ文字列を参照する可能性あり。");   }else{    System.out.println("スレッドセーフです。");   }   // 毎回、明示的にnewします。   String str_2    = new String("2つ目");   String str_2_2   = new String("2つ目");   String str_2_2_2  = new String("2つ目");   String str_2_2_2_2 = new String("2つ目");   if(str_2 == str_2_2 || str_2 == str_2_2_2             || str_2 == str_2_2_2_2){    System.out.println("3つ以上の参照変数が、同じ文字列を参照する可能性あり。");   }else{    System.out.println("スレッドセーフです。");   }  } }

JINJapan
質問者

補足

すみません。まったく意味がわかりません。 なぜ3つ以上の参照変数が同じ文字列を参照する可能性があると スレッドセーフじゃないのか。 上記に提示していただいたソースが何をやっているかはわかりますが、 質問内容とどう関係してるのかよろしければ解説ねがいますか?

関連するQ&A

  • stringについて

    確認したいのですが、ある関数の引数はconst string& strでやる場合 文字列リテラルは、ヒープが確保してそれをポインタであるstringに渡される。だからコピーされる手間が減るとういことでよろしいのでしょうか? 環境はvisual C++ 2005です。

  • Stringとは一体何だ?

    Stringは型なのでしょうか?それともクラスなのでしょうか? Stringは参照型の型で、クラスを表す、つまり文字列を表す参照型の型であり文字列を表すクラスでしょうか?説明が悪くてごめんなさい。Java歴二週間です。

    • ベストアンサー
    • Java
  • Stringオブジェクトについて

    ある参考書では、Java のメモリー使用効率を改善するために、JVM は「String 定数プール」と呼ばれる特別なメモリー領域を確保していると書いてあり、String を作成する例として次の2つのパターンのコードについて説明している(この例では、定数プール内にほかのString は存在しないものとしている)。 ・パターン(1) String s = "abc"; // 1つのString オブジェクトと         // 1つの参照変数を作成する この例では、"abc" がプールに納められ、変数s がそれを参照する。 ・パターン(2) String s = new String("abc"); // 2つのString オブジェクトと                  // 1つの参照変数を作成する。 このコードでは、new キーワードを使ったので、新しいString オブジェクトが標準の(プールでない)メモリー上に作成され、変数s がそれを参照する。さらに、リテラル"abc" がプールに収められる。  そこで質問ですが、パターン(2) で、変数s と2つのオブジェクトはそれぞれ互いにどのような関係(メモリー上の関係も含めて)を持っているのか。 例えば変数s に対してプリント命令を出したときにJVM はこの2つのオブジェクトに対してどのような処理をするのか。 またこれらのオブジェクトのhashcode はどうなっているのでしょうか。どなたか教えてください。

  • Stringクラスの変数の格納アドレスを知りたい

    いつもお世話になります。 Javaの文字列クラスのStringは参照型ですが、この変数の値が格納されたアドレスを知るためにはどうすればよいのでしょうか。eclipse上で、文字列の変数に対してtoString()を試してみたところ、格納されている文字列が出力されました。 ※自作したクラス、たとえばtest.MyClassだとすれば、toString()を用いれば「test.MyClass@01234」というような表記で出力されますが、このような情報を取得するにはどうすればよいでしょうか。 宜しくお願いします。

    • ベストアンサー
    • Java
  • WindowsのUNICODEをJavaのStringに変換したい

    Windowsからソケット通信でUNICODE(little endian)文字列を受け取っています。 bufferはバイト配列で格納されているとして String text= new String(buffer);とか String text= = new String(buffer,"MS932");とか String text= new String(buffer,0,長さ,"UNICODE"); などとするのですが漢字コードが化けてしまいます。 エンディアン並びを逆にしたりしましたがやはり同じです。 半角の場合、例えば「abc」なら「 a b c」と 0x0の部分がスペースになっていました。 ところでWindowsがメモ帳などではき出すunicodeはjavaのunicodeとは違う と聞きましたがどうなんでしょうか? 宜しくお願いします。 ※バイト配列をそのまま返すとそれをWindowsクライアントは表示するので 通信部分でバイト配列が壊れている事は考えにくいです。

    • ベストアンサー
    • Java
  • String文字列の解析の方法(初歩的ですみません

    皆様、はじめまして。sakiと申します。 javaを習い始めて2週間の初心者です。 今回はどうしてもわからな問題があり、質問することに致しました。 どうぞよろしくお願いします。以下、問題です。 String文字配列のaaa[SAKI]and[DOG]like[DOG=5]love[SAKI=-20]を左からj順に解析していく。 [ ]で囲まれていない文字列はString文字列として返す。 [ ]が現れた場合は、中身が"SAKI"の場合は、String型文字列"SAKI"を返す。 [ ]の中身が"DOG"の場合は、String型文字列"DOG"を返す。 また[ ]の中に=がある場合は=の後ろの数字をint型で返す。 という処理がわかりません。 for文とcharAt()メソッドで1文字ずつ抜き出し、それをchar型配列に格納し、さらにString型に変換して判別するという方法を考えたのですが上手くいきませんでした。 ご親切な方がいらっしゃいましたら、どうぞよろしくお願いいたします。

  • Stringの連結

    VB.netでのWindowsアプリケーション開発をしています。 String文字列の連結においてOutofMemory.Exceptionのエラーがスローされます。 手法としてはSingleの数値をカンマで区切り、1000個のカンマ区切り文字列を作成します。 その文字列は「temp_Str as String」の変数に格納していくのですが、 大型のループ処理で10万件以上作成されたところで上記のエラーが発生します。 (時間にして2~3時間程度経過した時点) 少なくとも数100万件の処理を行いたいのですが、 うまくメモリー管理をする方法はないでしょうか? 今現在GC.CollectやRemove等の処理は入れているのですが、あまり効果がありません。 よろしくお願いいたします。

  • コンピュータ用語のstringの由来

    コンピューター用語だとstringは文字列と言う意味ですが、一般用語だと紐と言う意味ですよね? なぜ紐が文字列になってるのでしょうか?

  • String配列を扱うアルゴリズムについて

    よりパフォーマンスの良いアルゴリズムが、 ございましたらご教示下さい。 数レコード分のDBテーブルデータが格納されたString[][]型が存在するとします。 配列の要素は、String[行(フィールド)][列(カラム)]です。 ここで、全レコード中の列ごとの最大文字列長を int[]型に取得したいと思います。 そうした場合、自作した下記の処理よりも、 よいパフォーマンスを得られるアルゴリズムがございましたら、 ご教示願いたいと思います。 ※処理前提条件 ●String[][]型変数に、過不足無くテーブルデータが格納済みであるとします。 ●配列の第一(行)・第二(列)要素の最大値は取得済みであるとします。 ////////////// // 変数定義 // ////////////// String[][] tableData; ← テーブルデータ格納済み(過不足はありません) int 行数 = 全行数(取得済み); int 列数 = 全列数(取得済み); //列毎の最長文字列値を格納する。 int[] maxLen = new int[列数]; ////////// // 処理 // ////////// //列の個数分、処理を繰り返す for(int i = 0; i < 列数; i++) {   //行の個数分、処理を繰り返す   for(int j = 0; j < 行数; j++) {     //NULLを回避する     if(tableData[i][j] != null) {       //int配列に格納済みの数値より大きければ、改めて格納する       if(maxLen[i] < tableData[i][j].length()) {         maxLen[i] = tableData[i][j].length();       }     }   } } 以上です、どなかお知恵をお貸し頂けませんか。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • RSetとString関数の質問

    String(3,255)という変換の結果は何ですか。 Dim MyString MyString = "0123456789" ' 文字列を初期化します。 Rset MyString = "Right->" ' MyString に " Right->" を格納します。 "0123"が空白になりますか。助けてください。お願いします。

専門家に質問してみよう