目录
构造方法
在创建对象的同时,初始化属性的值。
如何定义构造方法:
访问修饰符 类名称(参数) {
}//参数的有无会决定构造函数的类型
注:构造函数没有返回结果,所以不需要写返回值类型(void ,string ,int……)
案例1
public class User {
public String username;
public int age;
public User(String username, int age) {
// 使用两个参数的构造函数,初始化属性
this.username = username;
this.age = age;
}
// 将无参的构造方法,实现
public static void main(String[] args) {
// 在实例化对象的同时,将属性的值,通过构造函数赋予
User u1 = new User("麦当", 16);
System.out.println(u1.age);
System.out.println(u1.username);
User u2 = new User(); // 默认提供一个无参的构造方法
}
}
此时我们已经定义了一个有参的构造方法,但此时构建对象u2报错
注意:在java中,当我们定义了一个类之后,如果没有定义构造方法,则JVM在运行时会自动生成一个无参的构造,让我们使用 如果我们定义了构造方法,则不会再生成无参构造
在java中,当定义了一个类后,不管有没有写其他的构造函数,无参的构造一定要写一个。
public User() {
}
将上述代码写到第一段代码,此时构建对象u2不会报错
this关键字
在之前学习函数之间调用时,可以通过函数名进行调用。可是针对构造函数,无法通过构造函数名来相互调用,构造函数之间的调用可以通过this 关键字来完成。
在java中,this的关键字,this关键字是一个指针
在类中,this默认指向当前类。
如果构造对象,当对象构造完成后,会有一个this指向当前对象
三个功能:
1.区分成员变量与局部变量
2.代表当前对象
3.构造方法与构造方法之间的调用
public class User { public String username; public int age; public User(String username, int age) { // 使用两个参数的构造函数,初始化属性 this.username = username; this.age = age; } }
案例:this.username 指的是成员变量 username是局部变量(本来不能同名)
成员变量分配到堆中,局部变量分配到栈中
注:this只能在方法内部使用,表示对“调用方法的那个对象”的引用。但要注意,如果在方法内部调用同一个类的另一个方法,就不必使用this,直接调用即可。
同时,在没有对象参与的时候this默认指向当前类,但当有对象参与时,谁调用他,this就指向哪个对象
案例
public class User { public String username; public int age; publc void say{ System.out.println("我的名字是"+this.username) } public User(String username, int age) { // 使用两个参数的构造函数,初始化属性 this.username = username; this.age = age; } public static void main(String[] args) { // 在实例化对象的同时,将属性的值,通过构造函数赋予 User u1 = new User("麦当", 16); u1.say() } }
此时this指向u1这个对象
static关键字
static:静态的
- 可以修饰java的类、属性、方法
- static如果修饰类,只能修饰内部类
- 可以修饰属性,如果使用static修饰属性,该属性就是静态属性属于类,可以通过类 名直接访问
- 可以修饰方法,静态方法,属于类。
- static也可以直接单独使用,被static单独使用的语法块,静态块
- 静态块:静态块,会最先被类加载,而且只加载一次!!!
- static也可以修饰import (import static 包.*)
- static修饰的东西,提前加载内存中
在类中:
正常的属性和方法,都是为对象提供的,都是属于对象
类型 对象名称 = new 构造函数();
对象名称.属性
对象名称.方法()
如果类里面的属性或者方法被static,那这些就属于类。
类的成员:
属性
方法
构造方法
静态代码块
静态方法
静态属性
构造代码块
构造代码块:
直接定义在类中{}
相当于构造函数,在构造函数调用前会被触发
java中类成员在构造(对象创建的时候)的调用顺序
- 属性
- 静态属性
- 构造方法
- 静态代码块
- 构造代码块
注:方法只有只有调用了才会执行
当一个类被初始化时:
|-- 首先执行的是被static修饰部分:
根据顺序依次执行:
静态属性会被初始化
静态代码块(只加载一次)被触发
|-- 当static修饰的部分结束后:
开始执行普通属性和构造代码块
谁先执行,还是看顺序
|-- 最后执行构造函数,等构造函数执行完成,对象就已经创建成功!!
public class Student {
// 普通属性
public String name;
public String email;
public ClassRoom cr1 = new ClassRoom("java");
// 静态属性
public static ClassRoom cr2 = new ClassRoom("python");
// 静态代码块
static {
System.out.println("静态代码块开始执行了~~~~~~~");
}
// 构造代码块
{
System.out.println("构造代码块已经执行了");
}
// 构造函数
public MiddleStudent() {
System.out.println("普通的构造函数开始执行了……");
}
public static void main(String[] args) {
Student ms = new Student();
}
}
运行结果:
python
静态代码块开始执行了~~~~~~~
java
构造代码块已经执行了
普通的构造函数开始执行了……
注:若位置发生调换,结果会有一定的改变。
案例2:
public class Order {
static int num = 0;
String name = "qw";
static String name2 = "wwwwwwwwwww";
static Order parentClass = new Order(); // 第二次初始化对象,static部分不会再触发
Order() {
System.out.println("这里是构造函数*************");
}
{
System.out.println("name1:" + name);
System.out.println("这里是块1============");
}
static {
num += 1;
System.out.println("parentClass.name:" + parentClass.name);
System.out.println("这里是静态块*************" + num);
}
public static void main(String[] args) {
// 构造函数的执行顺序问题
new Order();
}
}
运行结果:
name1:qw
这里是块1============
这里是构造函数*************
parentClass.name:qw
这里是静态块*************
name1:qw
这里是块1============
这里是构造函数*************
注:这里构造代码块,与构造函数先执行
因为static Order parentClass = new Order();触发了新的函数执行栈,所以没机会执行static代码块,所以执行构造代码块,又因为后面再次调用该类所以还会重新输出一份。按照之前的该有的顺序。(静态,构造)