构造方法用于对象创建时给对象中的成员进行初始化,java初始化
要让这串代码通过编译,很简单,只需要在正式使用a之前,给a设置一个初始值就好
那么对于创造好的对象来说,我们也要进行相对应的初始化
我们先写一个Mydate的类public class MyDate { public int year; public int month; public int day; /** * 设置日期:
我们知道再Java方法内部定义一个局部变量的时候,必须要初始化,否则就会编译失败
要让这串代码通过编译,很简单,只需要在正式使用a之前,给a设置一个初始值就好
那么对于创造好的对象来说,我们也要进行相对应的初始化
我们先写一个Mydate的类
public class MyDate { public int year; public int month; public int day; /** * 设置日期: */ public void setDate(int year,int month,int day) { this.year = year; this.month = month ; this.day = day; } public void printDate() { System.out.println("年:" this.year "月:" this.month "日:" this.day); } public static void main(String[] args) { // this.printDate(); MyDate myDate = new MyDate(); myDate.setDate(2022,3,25); myDate.printDate(); MyDate myDate2 = new MyDate(); myDate2.setDate(2022,3,28); myDate2.printDate(); }}复制代码我们可以看到,在Mydate类中,要在调用之前实现写好setDate才能将具体的日期设置到对象当中
我们通过这个例子就可以发现两个问题:
每次对象创建好之后调用setDate方法设置具体时期,比较麻烦,那么对象该如何初始化呢?局部变量必须要初始化之后才能使用,那么为什么字段声明之后没有给初值,它依旧可以使用呢?答案:
我们可以运用构造函数来进行初始化因为这里和main函数中定义的局部变量不同,编译器会自动为你的字段声明的局部变量赋初始零值。:bento: 构造方法当我们实例化一个对象的时候:必须会有这两步,但并不是一定只有这两步
为对象分配内存调用合适的构造方法构造方法(也称为构造器)是一个特殊的成员方法, 名字必须与类名相同,在创建对象的时候,由编译器自动调用,并且在整个对象的生命周期内只调用一次
class Person { public String name; public int age; //构造方法: //名字与类名相同,且没有返回值类型,void也不行 //一般情况下使用public修饰 //在创建对象的时候由编译器自动调用,并且在对象的声明周期内只调用一次 public Person(String name,int age){ this.name = name; this.age = age; System.out.println("构造方法被调用了") } public void eat() { System.out.println("吃饭!"); } public void sleep() { System.out.println("睡觉!"); } public static void main(String[] args){ //在此处创建了一个Date类型的对象,并没有显式调用构造函数 Person p = new Person("xiaohong",18); p.eat(); } }复制代码:warning::构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间
:pizza: 特性名字必须和类名相同没有返回值类型,void也不行创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生)构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)class Student { //属性:成员变量-》类的内部 方法的外部的 public String name; public int age; public double score ; public String sex; public Student() { //调用本类中 带有2个参数的构造方法,第一个参数的类型是String,第2个参数的类型是int this.age = 18; System.out.println("这个是不带参数的构造方法!"); } public Student(String name,int age) { //this(); this.age = age; this.name = name; System.out.println("这个是带2个参数的构造方法!"); } public Student(String name, int age, double score, String sex) { this.name = name; this.age = age; this.score = score; this.sex = sex; System.out.println("带4个参数的构造方法!"); } public void doClass() { System.out.println(name "正在上课!"); //this.doHomeWork(); } public void doHomeWork(){ System.out.println(name "正在写作业"); } public void show() { System.out.println("姓名:" name " 年龄:" age " 学分:" score " 性别:" sex); }}//重载的时候复制代码
上述方法中:名字相同,参数列表不同,因此构成了方法重载
如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的。
class MyGirlFired { public String name; public int age; public String eyes; public void eat() { System.out.println("吃火锅!"); }}复制代码在上面的代码中,没有定义任何构造方法,编译器就会默认为我们生成一个不带参数的构造方法
:warning:: 一旦用户定义了,编译器则不再生成任何构造函数
class MyGirlFired { public String name; public int age; public String eyes; public MyGirlFired(String name,int age){ this.name = name; this.age = age; } public void eat() { System.out.println("吃火锅!"); } public static void main(String[] args) { //如果编译器会生成,则生成的构造方法一定是无参数的 //则此处创建对象是可以通过编译的 //但实际上会报错 MyGirlFired xHong = new MyGirlFired(); }}复制代码
在构造方法中,可以通过this调用其他构造方法来简化代码
class Student { //属性:成员变量-》类的内部 方法的外部的 public String name; public int age; public double score ; public String sex; public Student() { //调用本类中 带有2个参数的构造方法,第一个参数的类型是String,第2个参数的类型是int this("yumi",18); //this("bit3",99,98.9,"女"); System.out.println("这个是不带参数的构造方法!"); } public Student(String name,int age) { //this(); this.age = age; this.name = name; System.out.println("这个是带2个参数的构造方法!"); } public Student(String name, int age, double score, String sex) { this.name = name; this.age = age; this.score = score; this.sex = sex; System.out.println("带4个参数的构造方法!"); } public void doClass() { System.out.println(name "正在上课!"); //this.doHomeWork(); } public void doHomeWork(){ System.out.println(name "正在写作业"); } public void show() { System.out.println("姓名:" name " 年龄:" age " 学分:" score " 性别:" sex); }}复制代码:warning: 注意:
this()必须是构造方法中的第一条语句,且只能放在构造函数中不能形成“环”例如
绝大多数情况我们都用public来修饰,特殊场景下会被private修饰
默认初始化上面我们提到了一个问题:为什么局部变量在使用时必须要用初始化,而成员变量可以不用呢?
public class Date { public int year; public int month; public int day; public Date(int year,int month,int day){ //成员变量在定义之前,并没有给出初始值,那为什么就可以使用呢? System.out.println(this.year); System.out.println(this.month); System.out.println(this.day); } public static void main(String[] args) { //此处a并没有初始化,编译器报错; //Error:(24,28)Java:可能尚未初始化变量a //int a; //System.out.println(a); Date d = new Date(2022,3,29); }}复制代码要搞清楚这个过程,我们需要知道new关键字背后所发生的一些事情
Date d = new Date(2021,6,9);复制代码在程序层面只是简单的一条语句,而在JVM层面则需要做好多事情
检测对象对应的类是否加载了,如果没有加载则加载为对象分配内存空间处理并发安全问题:point_right:比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突
初始化所分配的空间即:对象空间被申请好了之后,对象中包含的成员已经设置好了初始值
数据类型
默认值
byte
0
char
'u0000'
short
0
int
0
long
0L
boolean
false
float
0.0f
double
0.0
reference
null
设置对象头信息(关于对象内存模型后面再说)调用构造方法,是给对象中的各个成员赋值:fried_shrimp:就地初始化在声明成员变量时,就直接给出了初始值
public class Date { public int year; public int month; public int day; public Date(){ System.out.println(this.year); System.out.println(this.month); System.out.println(this.day); } public Date(int year,int month,int day){ //成员变量在定义之前,并没有给出初始值,那为什么就可以使用呢? System.out.println(this.year); System.out.println(this.month); System.out.println(this.day); } public static void main(String[] args) { //此处a并没有初始化,编译器报错; //Error:(24,28)Java:可能尚未初始化变量a //int a; //System.out.println(a); Date d1 = new Date(2022,3,29); Date d2 = new Date(); }}//运行结果://0//0//0//0//0//0复制代码:warning: 注意 :代码编译完成之后,编译器会将所有成员初始化的这些语句添加到各个构造函数中
5.一个类至少会有1个构造函数,就算你没有写!
6.构造方法 本质 就是来实例化对象的时候调用
(1)分配内存
(2)调用合适的构造方法
7.this可以用来调用本类中的其他构造方法【构造方法当中使用】
且必须放在第一行!所以,只能在当前构造方法当中,调用一次
8.this的用法:
this.data 访问属性this.func(); 访问方法this(); //用来调用本类中的其他构造方法9.this不能形成环。
java对象初始化
1、java规定,构造方法中对其他构造方法的显式调用只能调用一次,且必须是第一句。每个构造方法的第一句java会自动加上对父类的默认方法的调用,这个是隐式的。而你的this调用是显式的,所以必须是第一句而且只能是一句。2、你对方法的理解是对的,方法的调用实际上用的是那段代码的入口,因此大家都用一个。
java中创建对象了,显示初始化值和构造函数初始化对象的区别?先后执行顺序是什么?
两个都可以初始化值,本质上没有区别,不同的是执行的先后。构造方法初始化值时需要包含有参的构造方法,创建对象时使用Object obj = new Object(arg1,arg2)的形式,你说的显示初始化值应该是使用set方法吧,比如obj.setArg1(arg1)的形式。执行顺序肯定是构造方法的形式要在前了,因为在对象创建之后就会给属性赋值,而set方法形式赋值只会在你调用set方法时才会赋值。再插一点题外话:其实在对象创建时成员变量已经初始化了,只是初始化的都是变量对应类型的默认值,比如int类型的默认值是0,引用类型默认值是null,boolean类型默认值是false。
文章评论