1.どのような種類のデータがありますか?それらの違いは何ですか?
2.変数の割り当ての過程で何が起こりましたか?
3.オブジェクトはいつ作成されますか?
データの種類
データ型は、基本型と参照型の2つの型に分けられます。その中で、文字列、整数などが一般的に使用される参照型です。
スタックとヒープについて話す
- スタックとヒープはこのブログの焦点ではないため、今日使用する必要のある知識ポイントについて簡単に説明します。以下に示すように、Javaで2つの変数aとbを宣言すると、2つの参照がスタックに生成されます。aは基本型intの変数であるため、aが宣言されたときにオブジェクトは作成されず、スタック内の値8のみを指します。bはラッパークラスString(参照型)の変数であるため、bが宣言された場合、bはスタックを指しますコンピュータが作成した「ok」文字列オブジェクトを見つけることができるアドレス。
- 2つの変数に値を割り当てる場合、1つのオブジェクトはスタック内の値を別のオブジェクトにのみ割り当てます。したがって、2つの参照型変数の間に値を割り当てると、システムはヒープ内にオブジェクトを自動的に作成しませんが、それらのアドレスが同じオブジェクトを指すようにします。
パラメータを変更するこれらの方法を比較してください
- まず、Studentクラスを作成する必要があります
public class Student {
public String name;
public int age;
public Student(){
}
public Student(String name,int age){
this.name=name;
this.age=age;
}
}
- 次に、ChangeDemoクラスを作成し、3つのメソッドを試してStudent cxdの年齢を変更し、結果がどうなるかを確認しましょう。
public class ChangeDemo {
public void change_1(int age){
age=age+1;
}
public void change_2(Student stu){
stu.age=stu.age+1;
}
public void change_3(Student stu){
stu=new Student(stu.name,stu.age+1);
}
public void test(){
//创建学生的初始对象
Student cxd=new Student("cxd",20);
//下面这三行代码分别单独测试,测试某一条时记得把其他两条注释掉!
change_1(cxd.age);
change_2(cxd);
change_3(cxd);
System.out.println(cxd.name+"的年龄是"+cxd.age);
}
public static void main(String[]args){
ChangeDemo cd=new ChangeDemo();
cd.test();
}
}
- 3つの方法の違いを観察し、実行結果を比較して、実行中に何が起こったかを慎重に検討します。
文の解釈: - メソッドchange_1で渡すパラメータはcxd.ageであり、システムはこのメソッドを呼び出すときに
int age=cxd.age;
ステートメントを自動的に実行します。この時間は、スタック上でint型の変数ageを宣言したのと同じであり、このageの値はcxd.ageと同じです。現時点では、ageとcxd.ageは互いに独立しており、ageを変更してもcxd.ageには影響しません。
- change_2で渡すパラメーターはcxdです。これは、Studentクラスの変数であり、参照変数のタイプに属します。このメソッドを呼び出すと、システムは
Student stu=cxd;
ステートメントを自動的に実行します。このステートメントは、スタック上のcxdと同じアドレスを持つ変数stuも宣言します。この時点でcxdとstuの両方のアドレスが同じオブジェクトを指しているため、この時点でstuを変更すると、stuアドレスが指すオブジェクトの値が変更されることに注意してください。最後に、cxd.ageを出力します。これはもちろん、出力が変更された後の値です。
- メソッドchange_3とメソッドchange_2で渡されるパラメーターは同じであるため、最初のステップは同じです。ステートメント
stu=new Student(stu.name,stu.age+1);
は新しいStudentオブジェクトを作成し、stuはこの新しいオブジェクトのアドレスを指すように更新されます。このとき、新しいStudentオブジェクトが変更され、元のStudentオブジェクトは影響を受けません。
- 簡単な要約:通常のメソッドを使用してパラメーターを渡す場合、渡すのはスタックの内容のみです。
Stringオブジェクトはいつ作成されましたか?
- 次のコードを任意のクラスのmain関数で実行して、まったく異なる結果を観察してみましょう。同様に、これらのプロセスで何が起こったのか考えてみてください。
public static void main(String[]args){
String a="ab";
String b="ab";
String c="abc";
String d="ab"+"c";
String e=new String("abc");
String f=a+"c";
String g=a+"c";
System.out.println(a==b);
System.out.println(c==d);
System.out.println(c==e);
System.out.println(c==f);
System.out.println(f==g);
}
-
出力を以下に示します。
-
小さな概念の説明は次のとおりです。シンボル " == "とメソッド " .equals() "を使用して、2つのStringクラスが等しいかどうかを比較します。前者は、スタック内の2つの変数のアドレスが等しいかどうかを判断します。同じ(つまり、2つが同じオブジェクトを指しているかどうかを比較する)、後者は、2つの文字列によって表される値が同じであるかどうかを判断します。(つまり、2つの文字列は同じ内容である可能性がありますが、2つの異なるオブジェクトです)
-
この一連のコードでは、文字列c、d、e、f、gはすべて「abc」ですが、「==」を使用してそれらが等しいかどうかを判断すると、以下に別の回答が表示されます。ブロガーは次のように説明します。 1。
-
a == bまず
String a="ab";
、このステートメントで何が実行されるかを理解する必要がありますか?このステートメントは、変数aを宣言するときに、最初にヒープ内で既製の「ab」オブジェクトを探し、存在しない場合は「ab」オブジェクトを作成します。存在する場合は、このオブジェクトを指すようにします。 。したがって、文字列a = "ab"を作成してから、文字列b = "ab"を作成すると、変数bはaによって作成された「ab」を指します。この時点で、「a == b」、つまりaとbのアドレスが同じであるかどうかを判断します。もちろん、答えは正しいです。 -
c == d前の例で、文字列a ==“ xxx”はオブジェクトを作成する特別な方法であると述べました。ここで、cとdはオブジェクトを作成するこの方法を使用するため、同じAnオブジェクトを指します。
-
c == e newメソッドを使用してオブジェクトを作成すると、ヒープ内に新しいオブジェクトが作成されます。したがって、新しいメソッドによって作成されたオブジェクトを指す変数は、もちろんどの変数とも等しくなりません。
-
c = = f; f == gの出力もfalseであり、fとgも新しいオブジェクトを作成したことを示しています。