먼저 날짜 클래스의 예를 작성해 보겠습니다.
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(); } }
위 코드는 날짜 클래스를 정의하고, 그런 다음 기본 메소드에서 세 개의 객체가 생성되고 classCode 클래스의 멤버 메소드를 통해 객체가 설정되고 인쇄됩니다. 코드의 전체 논리는 매우 간단하며 문제가 없습니다.
주의해야 할 두 가지가 있습니다:
1. 공식 매개변수 이름이 실수로 멤버 변수 이름과 동일합니다:
public void setDay(int year, int month, int day){ year = year; month = month; day = day; }
함수 본문에서 누가 누구에게 값을 할당합니까? 멤버변수에서 멤버변수로? 매개변수 대 매개변수? 멤버 변수에 대한 매개변수? 멤버 변수 매개변수?
2. 세 개체 모두 setDate 및 printDate 함수를 호출하지만 이 두 함수에는 개체에 대한 설명이 없습니다. setDate 및 printDate 함수는 어떤 개체의 데이터가 인쇄되는지 어떻게 알 수 있나요?
정식 매개변수 이름과 멤버 변수 이름이 다를 경우 할당 후 변수 값이 0이 되어 할당이 성공하지 못한 것을 알 수 있습니다.
우리는 어떻게 해야 할까요? 아래를보세요.
이 참조는 현재 개체(멤버 메서드가 실행 중일 때 멤버 메서드를 호출하는 개체)를 가리킵니다. 멤버 메서드의 모든 멤버 변수 작업은 이 참조를 통해 액세스됩니다. 모든 작업은 사용자에게 투명합니다. 즉, 사용자가 이를 전달할 필요가 없으며 컴파일러가 자동으로 완료합니다.
개선된 코드:
public void setDay(int year, int month, int day){ this.year = year; this.month = month; this.day = day; }
this 참조를 추가한 후 할당이 성공한 것을 확인할 수 있습니다.
기본적으로 추가됩니다. 추가하지 않더라도 기본적으로 this가 추가됩니다. 하지만 추가하지 않으면 형식적 매개변수 이름과 멤버변수 이름이 동일하면 문제가 발생합니다.
아래 코드에서 세 객체가 setDate 및 printDate 함수를 호출하는 것을 볼 수 있으며 설명이 없는데 어떤 객체의 데이터가 인쇄되고 있는지 어떻게 알 수 있습니까?
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); }
this를 사용하는 세 가지 방법:
this. 멤버 변수
this에 액세스합니다.
this()에 액세스합니다. 기능을 말합니다
"멤버 메소드"에서만 사용할 수 있습니다.
"멤버 메서드"에서는 현재 개체만 참조할 수 있으며 다른 개체는 참조할 수 없습니다.
이것은 "멤버 메서드"의 첫 번째 숨겨진 매개 변수로, 멤버 메서드가 실행될 때 컴파일러가 멤버 메서드 호출을 담당합니다.
객체의 참조는 멤버 메서드로 전달되며 이를 수신하는 역할을 담당합니다.
1.4 이 인용 연습
이름, 나이 등의 속성을 사용하여 학술 수업을 작성한 다음 메서드를 통해 이러한 속성의 값을 설정합니다. 둘째, 두 가지 메서드를 작성하고 이를 하나의 메서드로 사용합니다. 다른 메서드를 호출하세요.
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 객체 초기화 방법
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(); }//代码可以正常通过编译
객체를 생성할 때마다 setDate 메소드를 호출하여 특정 날짜를 설정하는 것이 번거롭습니다.
로컬 변수는 사용하기 전에 초기화해야 합니다. 필드가 선언된 후에도 값을 제공하지 않고 계속 사용할 수 있는 이유는 무엇입니까?
시공방법을 소개합니다. 그런 다음 내려다보세요.
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!