【Java 学习】构造器、static静态变量、static静态方法、static构造器、
Java类
- 1. 构造器
- 1.1 什么是构造器?
- 1.2 默认构造器
- 1.2.1 默认构造器
- 1.2.2 默认构造器初始化的数值
- 1.3 显示定义构造器
- 1.3.1 构造器的特点
- 1.3.2 构造器的定义格式
- 1.3.3 示例
- 1.4 构造器重载
- 1.5 this访问构造方法
- 2. static 静态
- 2.1 static 静态的定义
- 2.2 静态变量
- 2.2.1 静态变量和实例变量的区别
- 2.2.2 静态变量在类中的作用
- 2.2.3 访问静态变量
- 2.3 静态方法
- 2.3.1 静态方法与实例方法的区别
- 2.3.2 访问静态方法
1. 构造器
1.1 什么是构造器?
如果我们去手机店买手机,销售人员一般不会直接就给你推销最高配的手机,一般回先给你推销基础配置的手机(256G),如果自己想要选配的话就再进行选配。
构造器是什么呢?
构造器就是类设置的初始化成员变量的方法,当创建对象的时候,系统会默认初始化成员变量。
换言之,当我们创建对象(实例化类)的时候,类回调会用一个初始化自己的方法(),这个方法我们看不到,但是是存在的。编译器为了让我们可以设置自己的初始化方法,我们自己可以显示的创建初始化方法,但是,我们创建的初始化方法会覆盖编译器默认的初始化方法。
在Java中,这种初始化函数叫做构造器(构造方法)。
1.2 默认构造器
1.2.1 默认构造器
默认构造器(Default Constructor)是 Java 中的一个重要概念,它是由编译器自动生成的一种特殊的构造函数。当一个类没有显式地定义任何构造函数时,Java 编译器会自动为这个类提供一个无参数的构造函数,这就是默认构造器。默认构造器的主要作用是初始化新创建的对象,使其处于一个有效状态。
怎么验证默认构造器存在呢?
-
创建变量,然后打印变量:
public static void main(String[] args){ String brand; // 品牌 String color ; // 颜色 int memory; // 内存 System.out.println("brand:"+ brand); System.out.println("color:"+ color); System.out.println("memory:"+ memory); }
-
创建一个类,在类中创建成员变量,然后创建对象,打印出对象的成员变量:
public class Phone { String brand; // 品牌 String color ; // 颜色 int memory; // 内存 // 程序的开始 public static void main(String[] args){ Phone p = new Phone(); System.out.println("brand:"+ p.brand); System.out.println("color:"+p.color); System.out.println("memory:"+p.memory); } }
通过上述的两个测试,我们可以发现,在类中创建的成员变量自动被初始化过,即,类中有默认的构造器,当创建对象的时候会初初始化成员变量。
1.2.2 默认构造器初始化的数值
数据类型 | 默认值 |
---|---|
byte | 0 |
char | ‘\u0000’ |
short | 0 |
int | 0 |
long | 0L |
boolean | false |
float | 0.0f |
double | 0.0 |
reference | null |
1.3 显示定义构造器
1.3.1 构造器的特点
显示定义构造器的特点:
- 参数化:显示定义的构造器可以有零个或多个参数。通过参数化构造器,可以在对象创建时传递必要的初始化信息。
- 调用父类构造器:在子类的构造器中,可以通过 super 关键字调用父类的构造器。如果子类构造器的第一条语句不是 this(调用本类的其他构造器),那么编译器会自动插入 super() 调用。
- 初始化实例变量:构造器可以用来初始化类的实例变量,确保对象在创建时处于一个有效的状态。
- 执行初始化逻辑:除了初始化变量,构造器还可以执行其他必要的初始化逻辑,如资源分配、状态检查等。
1.3.2 构造器的定义格式
[访问修饰符] 类名{
// 构造器体
}
注:
- 构造器的名称必须与类名完全相同。
- 不写返回值类型。
- 创建对象的时候编译器自动调用构造器,不用显示调用。
1.3.3 示例
-
创建一个无参构造器
public class Phone { String brand; // 品牌 String color ; // 颜色 int memory; // 内存/G public Phone(){ brand = "华为"; color = "蓝色"; memory = 256; } }
当创建对象的时候就会把给成员变量赋值。
public class Phone { String brand; // 品牌 String color ; // 颜色 int memory; // 内存/G public Phone(){ brand = "华为"; color = "蓝色"; memory = 256; } // 程序的开始 public static void main(String[] args){ Phone p = new Phone(); System.out.println("brand:"+ p.brand); System.out.println("color:"+p.color); System.out.println("memory:"+p.memory); } }
-
创建有参构造器
public Phone(String brand, String color, int memory){ this.brand = brand; this.color = color; this.memory = memory; }
当创建对象的时候需要输入参数
public class Phone { String brand; // 品牌 String color ; // 颜色 int memory; // 内存/G public Phone(String brand, String color, int memory){ this.brand = brand; this.color = color; this.memory = memory; } // 程序的开始 public static void main(String[] args){ Phone p = new Phone("小米","黑色",512); System.out.println("brand:"+ p.brand); System.out.println("color:"+p.color); System.out.println("memory:"+p.memory); } }
1.4 构造器重载
看一个例子:
public static void main(String[] args){
// 传入参数
String s1 = new String("Hello World !");
// 不传入参数
String s2 = new String();
System.out.println("传入参数:" +s1);
System.out.println("不传入参数:"+s2);
}
像这种既可以传入参数又可以不传入参数的构造器是怎设置的呢?
答:这是构造器重载。构造器其实就是一个方法,既然是方法那么构造器也可以重载。
构造器重载:
public class Phone {
String brand; // 品牌
String color ; // 颜色
int memory; // 内存/G
// 带参构造器
public Phone(String brand, String color, int memory){
this.brand = brand;
this.color = color;
this.memory = memory;
}
// 无参构造器
public Phone(){
brand = "小米";
color = "黑色";
memory = 256;
}
// 程序的开始
public static void main(String[] args){
Phone p1 = new Phone("小米","黑色",512);
System.out.println("带参brand:"+ p1.brand);
System.out.println("带参color:"+p1.color);
System.out.println("带参memory:"+p1.memory);
System.out.println("_____________________________");
Phone p2 = new Phone();
System.out.println("无参brand:"+p2.brand);
System.out.println("无参color:"+p2.color);
System.out.println("无参memory"+p2.memory);
}
}
1.5 this访问构造方法
当我们在定义重载的构造方法时,可以使用this()
调用其他的构造方法。
怎么使用呢?
public class Phone {
String brand; // 品牌
String color ; // 颜色
int memory; // 内存/G
// 带参构造器
public Phone(String brand, String color, int memory){
this.brand = brand;
this.color = color;
this.memory = memory;
}
// 无参构造器
public Phone(){
this("小米","黑色",256);
}
}
图解:
2. static 静态
2.1 static 静态的定义
在 Java 中,static
关键字用于声明静态成员,包括静态变量(类变量)和静态方法。静态成员属于类本身,而不是类的实例。这意味着无论创建多少个类的实例,静态成员都只有一份副本。下面详细介绍 static 的使用和特点。
静态成员不依赖于类的特定实例,被类的所有实例共享,就是说 static 修饰的方法或者变量不需要依赖于对象来进行访问,只要这个类被加载,Java 虚拟机就可以根据类名找到它们。
调用静态成员的语法形式如下:
类名 . 静态成员
注意:
- static 修饰的成员变量和方法,从属于类。
- 普通变量和方法从属于对象。
- 静态方法不能调用非静态成员,编译会报错。
2.2 静态变量
2.2.1 静态变量和实例变量的区别
静态变量与实例变量的区别如下:
-
静态变量:
- 运行时,Java 虚拟机只为静态变量分配一次内存,在加载类的过程中完成静态变量的内存分配。
- 在类的内部,可以在任何方法内直接访问静态变量。
- 在其他类中,可以通过类名访问该类中的静态变量。
-
实例变量:
- 每创建一个实例,Java 虚拟机就会为实例变量分配一次内存。
- 在类的内部,可以在非静态方法中直接访问实例变量。
- 在本类的静态方法或其他类中则需要通过类的实例对象进行访问。
2.2.2 静态变量在类中的作用
作用:
- 静态变量可以被类的所有实例共享,因此静态变量可以作为实例之间的共享数据,增加实例之间的交互性。
- 如果类的所有实例都包含一个相同的常量属性,则可以把这个属性定义为静态常量类型,从而节省内存空间。例如,在类中定义一个静态常量 PI。
创建一个static变量:
创建一个同一部门的员工信息类,员工的部门是相同的,所以可以把存储部门的变量设置为静态的。
普通的成员变量有构造方法,静态成员有构造方法吗?
答:有。使用 static{}
创建。
// 员工信息类
public class People {
static String dept; //部门
String name; // 姓名
String age; // 年龄
int salary; // 工资
// 静态构造器
static{
dept = "java开发";
}
// 有参构造函数
public People(String name,String age, int salary){
this.name = name;
this.age = age;
this.salary = salary;
}
//无参构造函数
public People(){}
}
2.2.3 访问静态变量
类中的静态方法怎么访问呢?
答:可以像访问普通的变量那样,也可以使用使用类名+“.”进行访问。在该类的主函数中,可以直接使用静态的变量名进行访问。
-
使用创建的对象进行访问。
People p1 = new People(); System.out.println("使用 p1.dept 进行访问:" + p1.dept);
-
使用类名进行访问
System.out.print("使用 People.dept 进行访问:"+ People.dept);
-
在类的
main函数
中直接进行使用。public static void main(String[] args){ System.out.println("在类的main函数中直接使用:" + dept); }
总之,可以使用多种方法对静态变量进行访问,但是从类的静态变量角度来说,应该使用类名.静态变量名
进行访问。
修改静态静态便令也可以使用上述的方法吗?
答:可以。
2.3 静态方法
2.3.1 静态方法与实例方法的区别
静态方法与实例方法的区别如下:
- 静态方法不需要通过它所属的类的任何实例就可以被调用,因此在静态方法中不能使用 this 关键字,也不能直接访问所属类的实例变量和实例方法,但是可以直接访问所属类的静态变量和静态方法。另外,和 this 关键字一样,super 关键字也与类的特定实例相关,所以在静态方法中也不能使用 super 关键字。
- 在实例方法中可以直接访问所属类的静态变量、静态方法、实例变量和实例方法 。
2.3.2 访问静态方法
创建含有一个静态方法的类:
public class Money {
static int account; // 静态的钱数
// 静态构造器
static{
account = 1000;
}
// 买东西
public static void buy(){
account -= 100;
System.out.println("花钱,还剩钱:"+ account + "元");
}
// 挣钱
public static void earn(){
account += 10;
System.out.println("挣钱,还剩钱:"+ account+"元");
}
}
-
使用创建的对象访问
public static void main(String[] args){ Money m = new Money(); m.buy(); }
-
使用类名调用
public static void main(String[] args){ Money m = new Money(); m.buy(); // 使用类名 Money.buy(); }
-
在类的
main方法
中直接访问public static void main(String[] args){ Money m = new Money(); m.buy(); // 使用类名 Money.buy(); // 在main方法中直接访问 earn(); }
运行的结果为:
同学们看一看这个static方法
写的对不对?
public class Money {
int account; // 钱数
// 静态构造器
static{
account = 1000;
}
// 买东西
public static void buy(){
account -= 100;
System.out.println("花钱,还剩钱:"+ account + "元");
}
// 挣钱
public static void earn(){
account += 10;
System.out.println("挣钱,还剩钱:"+ account+ "元");
}
}
这是一个错误的例子,为什么呢?
答:静态方法中不能使用 this 关键字,也不能直接访问所属类的实例变量和实例方法。