JAvaパラメータ転送
4822 ワード
パラメータ伝達の問題を1つの問題から導入する
JAvaが言語になった場合
Javaプログラミング言語には値伝達パラメータしかありません.
Javaパラメータは、元のタイプでも参照タイプでもコピーが渡されます(別の言い方ではパスですが、パスコピーの方が理解しやすいでしょう.パス値は通常、アドレスに対してです).
パラメータタイプが元のタイプである場合、伝達されるのはこのパラメータのコピー、すなわちこの元のパラメータの値であり、これは前に述べた伝達値と同じである.関数でレプリカの値を変更するも元の値は変更されない.
パラメータタイプが参照タイプである場合、この参照パラメータのコピーが渡され、このコピーにはパラメータのアドレスが格納されます.このコピーのアドレスを関数で変更せずにアドレスの値を変更した場合、関数内の変更は入力パラメータに影響します.関数でnewのようにコピーのアドレスを変更すると、コピーは新しいアドレスを指し、このとき入力されたパラメータは元のアドレスを指すので、パラメータの値は変更されません.
理論に基づいて私たちは上の問題を分析します.
今あなたの問題は明らかになりました.
メモリの観点から説明します
xを定義するとき.
変数x-->[格納値0]
m(x,y)を実行する場合.変数xは値0を1部コピーしnumberで指す
変数number-->[コピーした値を格納0]
このときnumberに対して値を1に変更する.
number-->[格納値1];
このとき、numberの値はxと完全に何の関係もないことに気づきます.だから、xがなぜ変わっていないのか理解できます.
次に配列を説明します.
yを定義するとき.yはオブジェクトであるため,yは実際の配列位置を指すアドレスである.
変数y-->[格納配列アドレスY]
m(x,y)を実行する場合.変数yは値配列アドレスYを1部コピーしnumbersで指す
変数numbers->[コピーされた格納配列アドレスY]
このとき、numbersとyは実は同じアドレスを指していることに気づきます.つまり、同じオブジェクトです.だから、付与に成功したことに気づきます.
実は、このコードを試してみると、もっと面白いことがわかります.
ここで.numbersは割り当てに失敗しました.なぜか考えてみましょう.
簡単です.
yを定義するとき.yはオブジェクトであるため,yは実際の配列位置を指すアドレスである.
変数y-->[格納配列アドレスY]
m(x,y)を実行する場合.変数yは配列アドレスYを1部コピーしnumbersで指す
変数numbers->[コピーされた格納配列アドレスY]
実行new int[10] numbersへのアドレスの参照を割り当てる.
変数numbers->[new出てきた配列の新しいアドレス]
この时.numbersのアドレス参照はyの参照アドレスとは异なります.つまり変数numberの効果と同じです.そのため付与に失败しました.
Javaのストレージについて
実はjavaにとって、オブジェクトがどのように格納されているのか、戸惑う人がいます.前の問題は、いったいいつ値が伝達され、いつアドレス値が伝達されているのかということです.
1.スタック(stack)とスタック(heap)は、JavaがRamにデータを格納する場所です.C++とは異なり、Javaはスタックとスタックを自動的に管理し、プログラマーはスタックまたはスタックを直接設定することはできません.
2.スタックの利点は、CPUに直接配置されるレジスタに次ぐアクセス速度がスタックよりも速いことである.しかし、欠点は、スタック内のデータサイズと生存期間が決定されなければならず、柔軟性に欠けていることである.また、スタックデータは共有可能であり、詳細は3点目を参照してください.スタックの利点は、メモリサイズを動的に割り当てることができ、生存期間もコンパイラに事前に伝える必要がなく、Javaのゴミ収集器が使用しなくなったデータを自動的に回収することです.しかし、欠点は、実行時にメモリを動的に割り当てるため、アクセス速度が遅いことです.
3.Javaのデータ型は2種類あります.
i.1つは基本タイプ(primitive types)で、int、short、long、byte、float、double、boolean、char(stringの基本タイプはないことに注意).このタイプの定義は、int a=3のようなものである.long b = 255L;と呼びます.なお、自動変数は、クラスのインスタンスではなく、クラスの参照ではなく、ここではクラスの存在はありません.例えばint a=3;ここでのaはintタイプへの参照であり,3という字面値を指す.これらの額面値のデータは,大きさが知ることができ,生存期間が知ることができ(これらの額面値はあるブロックに固定定義され,ブロックが終了するとフィールド値が消失する),速度を追求するためスタックに存在する.(特殊なのはStringもスタックに格納されます.)
ii.もう1つは、Integer、String、Doubleなど、対応する基本データ型をパッケージするクラスデータです.これらのクラスデータはすべてスタックに存在し、Javaはnew()文でコンパイラに実行時に必要に応じて動的に作成されるため柔軟であるが、より多くの時間を費やすのが欠点である.
iii.Stringは特殊なパッケージクラスデータです.すなわち、String str=new String(「abc」)を用いることができる.の形式で作成したり、String str=“abc”で作成したりすることができます.の形式で作成します(比較として、JDK 5.0以前にInteger i=3を見たことがありません;の式は、クラスと文字の値がStringを除いて通用しないためです.JDK 5.0では、この式は可能です!コンパイラがバックグラウンドでInteger i=new Integer(3)の変換を行うためです).前者は、Javaではすべてオブジェクトであり、オブジェクトはクラスのインスタンスであり、すべてnew()の形式で作成される仕様のクラスの作成プロセスです.Javaには、DateFormatクラスなどのクラスがあり、このクラスのgetInstance()メソッドで新しく作成されたクラスを返すことができますが、この原則に違反しているようです.実はそうではありません.このクラスは、クラスのインスタンスを返すために単一のインスタンスモードを使用しますが、このインスタンスはクラス内部でnew()によって作成され、getInstance()はこの詳細を外部に隠します.なぜString str=「abc」なのか.では、new()でインスタンスを作成していませんが、上記の原則に違反していますか?実はありません.
Javaが渡すパラメータでは、フォント値とアドレス値は何ですか?
実はとても简単で、基本的なタイプの伝达のはすべて字面の値です.つまり直接スタックの中の値に保存します.
Double、Integerなど , ユーザーがカスタマイズした様々なObjectにはオブジェクトアドレスが渡されます.スタックに存在するためです.異なるのはDoubleとIntegerだけでは変更できないタイプです.new Integerを再newすることで値を変更するしかありません.このように、アドレスは依然として変化し、mianメソッドの値を変更することはできません.
なぜjavaは値伝達なのか.
Javaが渡すオブジェクトはすべてスタックの値であることがわかります.javaはこの方法でポインタを避けました.比較することができます.
cでは、このようなパラメータ伝達があります Dog *d , JavaにはないのはDog d.だけです.つまりjavaにはこのタイプを単独で定義していません.実際に渡されているのもアドレスです.しかし、javaには引用されていないという説は.私たち自身が定義することを避けました(この考えはゴミ回収と同じで、何かを定義する必要はないと思います....)伝達するのは値か引用かです.だから、この問題は、実はあまり論争する必要はありません.ただ理解すればいいだけです.
public static void main(String[] args) {
int x=1;
int[] y =new int[10];
m(x,y);
System.out.println("x is "+ x);
System.out.println("y[0] is "+ y[0]);
}
public static void m(int number , int[] numbers) {
number=1001;
numbers[0]=5555;
}
x is 1
y[0] is 5555
x y[0]
JAvaが言語になった場合
Javaプログラミング言語には値伝達パラメータしかありません.
Javaパラメータは、元のタイプでも参照タイプでもコピーが渡されます(別の言い方ではパスですが、パスコピーの方が理解しやすいでしょう.パス値は通常、アドレスに対してです).
パラメータタイプが元のタイプである場合、伝達されるのはこのパラメータのコピー、すなわちこの元のパラメータの値であり、これは前に述べた伝達値と同じである.関数でレプリカの値を変更するも元の値は変更されない.
パラメータタイプが参照タイプである場合、この参照パラメータのコピーが渡され、このコピーにはパラメータのアドレスが格納されます.このコピーのアドレスを関数で変更せずにアドレスの値を変更した場合、関数内の変更は入力パラメータに影響します.関数でnewのようにコピーのアドレスを変更すると、コピーは新しいアドレスを指し、このとき入力されたパラメータは元のアドレスを指すので、パラメータの値は変更されません.
理論に基づいて私たちは上の問題を分析します.
今あなたの問題は明らかになりました.
メモリの観点から説明します
xを定義するとき.
変数x-->[格納値0]
m(x,y)を実行する場合.変数xは値0を1部コピーしnumberで指す
変数number-->[コピーした値を格納0]
このときnumberに対して値を1に変更する.
number-->[格納値1];
このとき、numberの値はxと完全に何の関係もないことに気づきます.だから、xがなぜ変わっていないのか理解できます.
次に配列を説明します.
yを定義するとき.yはオブジェクトであるため,yは実際の配列位置を指すアドレスである.
変数y-->[格納配列アドレスY]
m(x,y)を実行する場合.変数yは値配列アドレスYを1部コピーしnumbersで指す
変数numbers->[コピーされた格納配列アドレスY]
このとき、numbersとyは実は同じアドレスを指していることに気づきます.つまり、同じオブジェクトです.だから、付与に成功したことに気づきます.
実は、このコードを試してみると、もっと面白いことがわかります.
public static void m(int number , int[] numbers) {
number=1001;
numbers = new int[10];
numbers[0]=5555;
}
ここで.numbersは割り当てに失敗しました.なぜか考えてみましょう.
簡単です.
yを定義するとき.yはオブジェクトであるため,yは実際の配列位置を指すアドレスである.
変数y-->[格納配列アドレスY]
m(x,y)を実行する場合.変数yは配列アドレスYを1部コピーしnumbersで指す
変数numbers->[コピーされた格納配列アドレスY]
実行new int[10] numbersへのアドレスの参照を割り当てる.
変数numbers->[new出てきた配列の新しいアドレス]
この时.numbersのアドレス参照はyの参照アドレスとは异なります.つまり変数numberの効果と同じです.そのため付与に失败しました.
Javaのストレージについて
実はjavaにとって、オブジェクトがどのように格納されているのか、戸惑う人がいます.前の問題は、いったいいつ値が伝達され、いつアドレス値が伝達されているのかということです.
1.スタック(stack)とスタック(heap)は、JavaがRamにデータを格納する場所です.C++とは異なり、Javaはスタックとスタックを自動的に管理し、プログラマーはスタックまたはスタックを直接設定することはできません.
2.スタックの利点は、CPUに直接配置されるレジスタに次ぐアクセス速度がスタックよりも速いことである.しかし、欠点は、スタック内のデータサイズと生存期間が決定されなければならず、柔軟性に欠けていることである.また、スタックデータは共有可能であり、詳細は3点目を参照してください.スタックの利点は、メモリサイズを動的に割り当てることができ、生存期間もコンパイラに事前に伝える必要がなく、Javaのゴミ収集器が使用しなくなったデータを自動的に回収することです.しかし、欠点は、実行時にメモリを動的に割り当てるため、アクセス速度が遅いことです.
3.Javaのデータ型は2種類あります.
i.1つは基本タイプ(primitive types)で、int、short、long、byte、float、double、boolean、char(stringの基本タイプはないことに注意).このタイプの定義は、int a=3のようなものである.long b = 255L;と呼びます.なお、自動変数は、クラスのインスタンスではなく、クラスの参照ではなく、ここではクラスの存在はありません.例えばint a=3;ここでのaはintタイプへの参照であり,3という字面値を指す.これらの額面値のデータは,大きさが知ることができ,生存期間が知ることができ(これらの額面値はあるブロックに固定定義され,ブロックが終了するとフィールド値が消失する),速度を追求するためスタックに存在する.(特殊なのはStringもスタックに格納されます.)
ii.もう1つは、Integer、String、Doubleなど、対応する基本データ型をパッケージするクラスデータです.これらのクラスデータはすべてスタックに存在し、Javaはnew()文でコンパイラに実行時に必要に応じて動的に作成されるため柔軟であるが、より多くの時間を費やすのが欠点である.
iii.Stringは特殊なパッケージクラスデータです.すなわち、String str=new String(「abc」)を用いることができる.の形式で作成したり、String str=“abc”で作成したりすることができます.の形式で作成します(比較として、JDK 5.0以前にInteger i=3を見たことがありません;の式は、クラスと文字の値がStringを除いて通用しないためです.JDK 5.0では、この式は可能です!コンパイラがバックグラウンドでInteger i=new Integer(3)の変換を行うためです).前者は、Javaではすべてオブジェクトであり、オブジェクトはクラスのインスタンスであり、すべてnew()の形式で作成される仕様のクラスの作成プロセスです.Javaには、DateFormatクラスなどのクラスがあり、このクラスのgetInstance()メソッドで新しく作成されたクラスを返すことができますが、この原則に違反しているようです.実はそうではありません.このクラスは、クラスのインスタンスを返すために単一のインスタンスモードを使用しますが、このインスタンスはクラス内部でnew()によって作成され、getInstance()はこの詳細を外部に隠します.なぜString str=「abc」なのか.では、new()でインスタンスを作成していませんが、上記の原則に違反していますか?実はありません.
Javaが渡すパラメータでは、フォント値とアドレス値は何ですか?
実はとても简単で、基本的なタイプの伝达のはすべて字面の値です.つまり直接スタックの中の値に保存します.
Double、Integerなど , ユーザーがカスタマイズした様々なObjectにはオブジェクトアドレスが渡されます.スタックに存在するためです.異なるのはDoubleとIntegerだけでは変更できないタイプです.new Integerを再newすることで値を変更するしかありません.このように、アドレスは依然として変化し、mianメソッドの値を変更することはできません.
なぜjavaは値伝達なのか.
Javaが渡すオブジェクトはすべてスタックの値であることがわかります.javaはこの方法でポインタを避けました.比較することができます.
cでは、このようなパラメータ伝達があります Dog *d , JavaにはないのはDog d.だけです.つまりjavaにはこのタイプを単独で定義していません.実際に渡されているのもアドレスです.しかし、javaには引用されていないという説は.私たち自身が定義することを避けました(この考えはゴミ回収と同じで、何かを定義する必要はないと思います....)伝達するのは値か引用かです.だから、この問題は、実はあまり論争する必要はありません.ただ理解すればいいだけです.