ができないのはなぜで文字列にすると変更可能なJavaます。います。

StackOverflow https://stackoverflow.com/questions/93091

  •  01-07-2019
  •  | 
  •  

質問

それは決定している文字列を変更不能なJavaます。純(およびその他の言語)?なぜないので変更可能な?

役に立ちましたか?

解決

による 有効なJava, 第4章のページを73,2nd edition:

"多くの理由とし不変なクラスが容易 デザイン、実施、使用により変更可能。ていると言っても過言ではありやすい についてを確保しております。

[...]

"変更不能なオブジェはシンプルです。 変更不能なオブジェクト うつ状態の状態で作成されます。まず すべてのコンストラクタをクラスの不変量である 保証されるこれらの不変量はtrueする時の人となり、 ありません。

[...]

変更不能なオブジェは、本質的にスレッドセ;が不要となる同期します。 ができない壊れた複数のスレッドによる ることに同意したものとみな同時に行います。この最も簡単なアプローチ をスレッドの安全性です。実は、スレッドできまを遵守し もう一つのスレッドに変更不能なオブジェクトです。そのため、 変更不能なオブジェクトを自由に共有

[...]

その他の小さなポイントから同一章:

で手に入れることができるシェア変更不能なオブジェですが、自分の炉内構造物.

[...]

変更不能なオブジェに大きくためのビルディング-ブロックその他の物から変更可能なまたは変更できません。

[...]

その唯一の欠点の不変なので授業はこれらの別々のオブジェクト毎に異なる値です。

他のヒント

少なくとも二つの理由

最初にセキュリティ http://www.javafaq.nu/java-article1060.html

主な理由文字列を作 不変でした。この 例:いファイルを開く方法 ログインチェック。またパス文字列 このメソッドを処理認証 に必要となる前にコ 渡します。また文字列 変更可能なすことができたかを 変更後の内容 認証チェック前のOSが からの依頼にプログラムで 可能な要請します。い場合 いをしないと、テキストファイル ユーザディレクトリがその後の が何らかの管理を変更 ファイル名をご入用の開 "passwdファイルまたはずです。その ファイルの変更が可能です でログインで直接OS.

二次メモリの効率化 http://hikrish.blogspot.com/2006/07/why-string-class-is-immutable.html

JVM内の文字列" きました。療のメモリ 効率のJVMを参照の文字列 オブジェクトからプールがあります。ませんの作成 の新しいStringオブジェクト。なので、いつ 自分の好きな名前を付けて新しい文字列リテラル,JVM チェックのプールかどうか 既に存在します。場合で 現在のプールでの への参照が同じオブジェクトを作成し の新しいオブジェクトのプールがあります。がありま する多くの参照点と同じ 文字列オブジェクトでは、あの変化に の値であり、影響するすべての 参照です。なので、日が決まで 変更できません。

実際に、理由文字列は不変でjavaではない。主に二つの理由は次の通りである:

Theadの安全性:

文字列は極めて広く使えるタイプのオブジェクトです。そのため以下を保証で使用するマルチスレッド環境です。文字列は変更できることを確認してください安全な共有の文字列の中でスレッド)。を変更不能な文字列あることを確認することと同時に渡す文字列からスレッドを別のスレッドBはスレッドBは予想修正のスレッドの文字列になります。

できるだけでなく、助けを簡素化していかに複雑なタスクのマルチスレッドプログラミングでも性能のマルチスレッド願います。アクセス可変オブジェクトから同期することができるアクセスから複数のスレッドを確証するために、一つのスレッドなどの値の読み取りのオブジェクトが変更に別のスレッド.適切な同期がん正常のプログラマー、高価を行います。変更不能なオブジェで改変を行うことはできませんがなに同期します。

性能:

ながら文字列interningれでは小さなゲインメモリの効率化のためのJavaプログラムみ文字列リテラルが保持されます。この文字列も、同じお ソースコード を共有し、同じ文字列オブジェクトです。の場合プログラムを動的に作成る文字列が同じで表現されるので異なるオブジェクト。

より重要なのは、変更不能な文字列をその内部データです。多くの文字列操作は、その基になる配列の文字があったときは、その文字の必要はありませんがコピーされます。例えば、言いたいの最初の文字の文字列になります。Javaでは、お電話myString.部分文字列(0,5).この場合、どの部分文字列()メソッドは単純に新しい文字列オブジェクト株式myStringの基礎となるchar[]が知り尽くしたことを開始インデックス0と終了インデックス5のことをchar[].このグラフは、すべてが終わるの

 |               myString                  |
 v                                         v
"The quick brown fox jumps over the lazy dog"   <-- shared char[]
 ^   ^
 |   |  myString.substring(0,5)

その結果、このような業務に非常に安く、O(1)年間もの長さに依存するための独自の文字列の長さの部分文字列を抽出してください。この行動はまた、いくつかのメモリの利点から、多くの文字列でそれらを支えるchar[].

スレッドの安全性およびます。場合は文字列で改変を行うことはできませんので安全に過ご参考周辺における複数スレッド)。場合の文字列が変更可能なす、いつものコピーのすべてのバイト文字列の新しいインスタンスを同期します。典型的アプリケーションを読み込み文字列の100倍の毎時間の文字列は変更する必要があります。見wikipediaに 不変性.

一すべきことだが、"なぜXすると変更可能な?" についてのデフォルト値は不変なので、すでに述べたよ 姫毛羽.のであれば、例外であること可変です。

残念ながら現在の多くのプログラミング言語のデフォルト値は可変性が、願わくは、将来のデフォルトではこのimmutablity参照 願いのが主流プログラミング言語).

一つの要因である場合、文字列が変更可能な、オブジェ保存文字列がさないよう注意してください店舗部ねその内部データを変更します。この文字列はかなりのプリミティブ型を数字のように、何ができるとして扱い渡された値による場合であっても、参照によって渡されるもの節約いたしました。

Wow!私ももっと成長しなけの記事はこちら。文字列を変更不能なものが無い。ばには既にアクセスのオブジェクトにランニング用いて行なった場合に想定されるようとしているのを防someone'ハッキング'の文字列にアプリ)があるということでハイレベルな技術を生かしたその他の機会のためにハックする

なるという斬新なアイデアの不変性の文字列はスレッド問題です。う~ん...しているオブジェクトが変更により異なる二つのスレッド)。う解決す。同期アクセスのオブジェクト?Naawww...そういうものに変更オブジェクトですべて--だ全ての汚並行処理で課題!とにしましょうすべてのオブジェクトが不変なので、そのsynchonized contructからJava言語です。

の理由が指摘するようにその他上記はメモリを最適化するでも共通ですの申請と同じ文字列リテラルを使用します。で共通しているが、実際にこの数十年前、多くのコンパイラの最適化だけを格納する単一のインスタンスの文字列リテラルです。の欠点で最適化であるランタイムコードを変更する文字列リテラルを紹介する問題ですので変更のインスタンスその他全てのコードは株式です。例えば、こんな機能がどこかに申請を変える文字列リテラル"犬"です。A printf("犬")のような"猫"書を標準出力に出力します。そのために必要なの護コードに変更することを試み文字列リテラルですe., して不変なため).一部のコンパイラ(ポらのOS)の達成を文字列に特殊な読み取り専用メモリセグメントが不適切と判断するメモリの断層の場合、書き込みを試みた。

Javaこのとして知られてinterning.Javaコンパイラここでは以下の標準メモリの最適化によるコンパイラです。そのためるとともに、同誌掲載号の注目の文字列リテラル変更にランタイム時において、Javaでは、Stringクラスは不変でしていますeまな仕掛け人が容易にする文字列のコンテンツ).文字列のようである必要はありません不変な場合はinterningの文字列リテラルなが発生します。

文字列はペイントされませんがプリミティブ型していくのか、普通にいを利用できるようにするには値を意味するようになります。

値はも信頼できる変わらない。書き込んだ場合: String str = someExpr(); いていない場合については、変更しないといstr.

文字列オブジェクトとしては当然のことながらポインタの意味、価値の意味などが必要で変更できません。

ごきげんよう、トメ子です、バンプが---いう不変の?を考えます。

public static unsafe void MutableReplaceIndex(string s, char c, int i)
{
    fixed (char* ptr = s)
    {
        *((char*)(ptr + i)) = c;
    }
}

...

string s = "abc";
MutableReplaceIndex(s, '1', 0);
MutableReplaceIndex(s, '2', 1);
MutableReplaceIndex(s, '3', 2);
Console.WriteLine(s); // Prints 1 2 3

まで延長方法。

public static class Extensions
{
    public static unsafe void MutableReplaceIndex(this string s, char c, int i)
    {
        fixed (char* ptr = s)
        {
            *((char*)(ptr + i)) = c;
        }
    }
}

には次の作業

s.MutableReplaceIndex('1', 0);
s.MutableReplaceIndex('2', 1);
s.MutableReplaceIndex('3', 2);

結論:彼らは、変更不能な状態であるにも知られているコンパイラです。の肩の上にのみ適用されます。純文字列としてJavaないポインタ.しかし文字列で完全に変更可能な利用のポインタのクライアントまで、フルのC#.なかにポインタが使用され、実際の使用でも安心してご使用いただける;もし、このように曲げると全体"の変更可能なルール"が存在します。でき、通常は変更の指標に直接文字列のはここだけです。それよりもこの未然に防ぐことができると考えるdisallowingポインタのインスタンスの文字列またはコピーを作時文字列が指摘が関する情報は見つかりませんでしを行い、文字列のC#ソースコードは完全に変更できません。

ほとんどの目的は、"文字列"が使われたりして-思想の想定すると有意義な 原子ユニット のように番号.

"なぜ、個々の文字の文字列は変更可能なこのように"なぜ人のビットの整数値は可変です。

知っておきたいかがでしょうか。かと常に思っています。

ているのは嫌だと言うが、残念ながら今は議論が当社の言語を吸い込み、という一言 文字列, めには、複雑な脈絡に位置す概念クラスのオブジェクトです。

して計算との比較"文字列"に似ています。場合の文字列は整数)を変更可能ないく特別なコードのロックの価値への変更不能な地形を行うためにはどのような計算も確実です。そのため、かのような文字列を数値識別子のものではなく、16,32または64ビット長できる数百人のビットの長さです。

誰かには"文字列"を考えれぞれだと思います。お思いの方も、単に文字のセットは、特定の目的は、できると信じており愕然とする人 決めたもの ることができない操作します。その"文字列"クラスだけではない文字配列この STRING, ではなく、 char[].ある基本的な前提をコンセプトにおいては参照としての"文字列"で一般的に記述できるとして意味のある原子ユニットの符号化データのような番号です。が話題"を操作文字列"かんの話を操作する 文字 の構築 文字列, は、StringBuilderがします。って少し考えてい単語文字列""真にします。

思えない場合は文字列が可変です。以下のAPI機能できる情報をもとに、最新版への帰国のための情報を異なるユーザーの場合 変更可能な ユーザー名の文字列は、意図的又は非意図的に改変した別のスレッドがこの機能を利用する

string GetPersonalInfo( string username, string password )
{
    string stored_password = DBQuery.GetPasswordFor( username );
    if (password == stored_password)
    {
        //another thread modifies the mutable 'username' string
        return DBQuery.GetPersonalInfoFor( username );
    }
}

安全保障なん'アクセス制御でも安全性や正確性を保証'.場合の方法は簡単に書きに依存を行う簡単な計算との比較-確実に、そしてなに安全を呼んでいるのですが、しば不安になるという問題はプログラミング言語そのものです。

不変ではないとのつながりが深ます。のためには、少なくとも。純くのSecureStringクラスです。

この商ます。文字列の文字列のプールを作成する場合複数の同一文字列と同じ。デザイナーのねこのメモリ保存方法にも共通の場合には、プログラムが研磨の文字列。

下振れるconcatenationsたくさんの文字列は移行かなゴミは、実際に害の記憶。まStringBuffer、StringBuilder(Javaでは、StringBuilderます。純利の保存メモリにこれらの例です。

この決定にて変更可能な文字列はC++の原因は多くの問題は、この優れた記事によるケルビンHenney約 狂牛病.

牛=コピーが書き出します。

文字列をJavaは真に不変な変更することができ、その価値の反射、またはクラスが得られる。でないことによって産ました。例参照: マトリックJava

不変性が良いです。なJava.またコピー文字列を毎回お渡しするようにしてください、このエラーが発生しやすいコードです。ものではありません混在しているので、改造に影響する。の整数を変更できるように振る舞いをint、文字列としての行動において不変のようなことをプリミティブ.C++を渡す文字列値ではなく明確に示すことでソースコード。

例外があほぼほぼすべての規則:

using System;
using System.Runtime.InteropServices;

namespace Guess
{
    class Program
    {
        static void Main(string[] args)
        {
            const string str = "ABC";

            Console.WriteLine(str);
            Console.WriteLine(str.GetHashCode());

            var handle = GCHandle.Alloc(str, GCHandleType.Pinned);

            try
            {
                Marshal.WriteInt16(handle.AddrOfPinnedObject(), 4, 'Z');

                Console.WriteLine(str);
                Console.WriteLine(str.GetHashCode());
            }
            finally
            {
                handle.Free();
            }
        }
    }
}

できます。かくシステムを安全にできない場合は信頼る文字列はtamperproof.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top