ホームページ >Java >&#&チュートリアル >Java でのこの参照とオブジェクト構築の初期化メソッド
これを書いてみましょうfirst 日付クラスの例:
public class classCode { public int year; public int month; public int day; public void setDay(int y, int m, int d){ year = y; month = m; day = d; } public void printDate(){ System.out.println(year + "-" + month + "-" + day); } public static void main(String[] args) { // 构造三个日期类型的对象 d1 d2 d3 classCode Date1 = new classCode(); classCode Date2 = new classCode(); classCode Date3 = new classCode(); // 对d1,d2,d3的日期设置 Date1.setDay(2022, 8, 9); Date2.setDay(2023, 8, 9); Date3.setDay(2024, 8, 9); //打印日期的内容 Date1.printDate(); Date2.printDate(); Date3.printDate(); } }
上記のコードは日付クラスを定義し、メイン メソッドで 3 つのオブジェクトを作成し、それらをメンバー メソッドに渡します。 classCode クラス オブジェクトを設定して出力するためのコードの全体的なロジックは非常に単純であり、問題はありません。
注意すべき点が 2 つあります:
1. 正式パラメータ名が誤ってメンバー変数名と同じです:
public void setDay(int year, int month, int day){ year = year; month = month; day = day; }
関数本体で誰が誰に値を割り当てるのか?メンバー変数からメンバー変数へ?パラメータからパラメータへ?メンバー変数へのパラメーター?メンバー変数パラメータ?
2. 3 つのオブジェクトはすべて setDate 関数と printDate 関数を呼び出していますが、これら 2 つの関数のオブジェクトについての説明はありません。setDate 関数と printDate 関数はどのオブジェクトのデータが印刷されているかをどのようにして知るのでしょうか?
仮パラメータ名とメンバー変数名が異なる場合、代入後の変数の値は 0 となり、代入が行われていないことがわかります。成功。 ######私たちは何をすべきか?下を向いてください。
1.2 この参照とは何ですか
すべての操作がユーザーに対して透過的であるというだけです。つまり、ユーザーが操作を渡す必要はなく、コンパイラーが自動的に操作を完了します。
改善されたコード:public void setDay(int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
}
参照を追加すると、割り当てが次のようになっていることがわかります。成功。 これはデフォルトで追加されます。 thisが追加されていない場合でも、デフォルトでthisが追加されます。ただし、追加しない場合、仮パラメータ名とメンバ変数名が同じ場合に問題が発生します。
次のコードでは、3 つのオブジェクトが
関数と printDate 関数を呼び出していることがわかりますが、説明はありません。どのようにすればわかるでしょうか。 1 つは印刷されていますか? オブジェクト データ? public static void main(String[] args) {
// 构造三个日期类型的对象 Date1 Date2 Date3
Date Date1 = new Date();
Date Date2 = new Date();
Date Date3 = new Date();
// 对Date1,Date2,Date3的日期设置
Date1.setDay(2022, 8, 9);
Date2.setDay(2023, 8, 9);
Date3.setDay(2024, 8, 9);
//打印日期的内容
Date1.printDate();
Date2.printDate();
Date3.printDate();
}
#
public void setDay(Date this, int y, int m, int d){ this.year = y; this.month = m; this.day = d; } public void printDate(Date this){ System.out.println(this.year +"-"+ this.month +"-"+ this.day); }#これを使用する 3 つの方法:
this.メンバー変数
「メンバー メソッド」では、現在のオブジェクトのみを参照でき、他のオブジェクトを参照できません。
public class Student { public String name; public int age; public void setStudent(String name, int age) { this.name = name; this.age = age; } public void printStudent() { System.out.println(this.name + "->" + this.age); } public static void main(String[] args) { Student student = new Student(); student.setStudent("zhangsan", 19); student.printStudent(); } }
2.1 オブジェクトの初期化方法
これまでの知識ポイントの学習を通じて、 Java メソッドでは、ローカル変数が内部で定義されている場合は初期化する必要があり、初期化しないとコンパイルが失敗することを知ってください。
public static void main(String[] args) { int a; System.out.println(a); }// Error:(26, 28) java: 可能尚未初始化变量a.オブジェクトの場合は、参照変数であるため、値が割り当てられていなくてもエラーは報告されません。
public static void main(String[] args) { // 构造一个日期类型的对象 Date date = new Date(); date.setDay(2022, 8, 9); //打印日期的内容 date.printDate(); }//代码可以正常通过编译
ローカル変数は使用する前に初期化する必要があります。フィールドが宣言された後も値を指定せずに使用できるのはなぜですか?
#施工方法をご紹介します。それから下を見てください。
2.2.1 概念
public class Student { public String name; public int age; public Student(){//这是一个构造方法 System.out.println("不带参数的构造方法"); } public Student(String name, int age) {//这是一个构造方法 System.out.println("带参数的构造方法"); this.name = name; this.age = age; } public void setStudent(String name, int age) { this.name = name; this.age = age; } public void printStudent() { System.out.println(this.name + "->" + this.age); } public static void main(String[] args) { Student student = new Student();//这一行是构造方法的调用 } }
Student student = new Student();
new在实例化对象,而实例化对象一定会调用构造方法。
注意:当我们没有提供构造方法时,编译器会自动提供一个不带参数的构造方法。
名字必须与类名相同。
没有返回值类型,设置为void也不行。
创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次。
构造方法可以重载(用户根据自己的需求提供不同参数的构造方法。
public Student(){//不带参数的构造方法 System.out.println("不带参数的构造方法"); } public Student(String name, int age) {//带两个参数的构造方法 System.out.println("带参数的构造方法"); this.name = name; this.age = age; }
上述两个构造方法:名字相同,参数列表不同,因此构成了方法重载。
如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的。
public class Work { public int one = 1; public int three = 3; public int two = 2; public void printWork() { System.out.println(one + "-" + two + "-" + three); } public static void main(String[] args) { Work work = new Work(); work.printWork(); } }
上述Work类中,没有定义任何构造方法,编译器会默认生成一个不带参数的构造方法。
那如何调用带参数的构造方法呢?
public class Work { public int one = 1; public int three = 3; public int two = 2; public Work(int one, int two, int three) { System.out.println("带参数的构造方法"); this.one = one; this.two = two; this.three = three; } public void printWork() { System.out.println(one + "-" + two + "-" + three); } public static void main(String[] args) { Work work = new Work(3, 6, 9); work.printWork(); } }
注意:一旦用户定义,编译器则不再生成。
构造方法中,可以通过this调用其他构造方法来简化代码。
public Work() { this(10, 20, 30);//调用本类当中其他的构造方法 System.out.println("不带参数的的构造方法"); } public Work(int one, int two, int three) { System.out.println("带参数的构造方法"); this.one = one; this.two = two; this.three = three; }
注意:
this调用必须在构造方法里面,
要在在第一行,
不能写成循环调用。
绝大多数情况下使用public来修饰,特殊场景下会被private修饰(后序讲单例模式时会遇到)
为什么使用成员变量不需要初始化呢?
在程序层面只是简单的一条语句,在JVM(以后讲)层面需要做好多事情,下面简单介绍下:
检测对象对应的类是否加载了,如果没有加载则加载
为对象分配内存空间
处理并发安全问题
比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突初始化所分配的空间
即:对象空间被申请好之后,对象中包含的成员已经设置好了初始值
比如:
设置对象头信息(关于对象内存模型后面会介绍)调用构造方法,给对象中各个成员赋值
定义成员变量的时候就已经赋值好了。
public class HardWork { public int a = 10;//就地初始化 public int b = 20;//就地初始化 public String c = "zhangsan";//就地初始化 public void setWork(int a, int b, String c) { this.a = a; this.b = b; this.c = c; } public void printWork() { System.out.println(a + "-" + b + "-" + c); } public static void main(String[] args) { HardWork work = new HardWork(); work.printWork(); System.out.println(); } }
注意:代码编译完成后,编译器会将所有给成员初始化的这些语句添加到各个构造函数中。
以上がJava でのこの参照とオブジェクト構築の初期化メソッドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。