JAVA中的构造器(构造方法) 构造器:构造器是一种方法,它的作用就是完成对对象的初始化
我们以前写代码是现将对象创建好,然后在该对象中的属性赋值,比如像下面这样:
public class Test{
public static void main(String[] args){
Person people = new People();
people.name = "冬泳怪哥";
people.age = 40;
people.hobit = "游泳";
}
}class People{
String name1;
int age;
String hobits;
}
这样赋值比较麻烦,为了解决这个问题,java开发者就写了一个构造器,它的作用就是帮助完成对象的初始化,我们要做的就是在创建对象的时候就完成对对象的初始化。列如像下面这样:
public class Test{
public static void main(String[] args){
Person people = new People("冬泳怪哥",40,"游泳");
}
}class People{
String name1;
int age;
String hobits;
//构造器是创建
public void People(String name,int age,String hobit){
this.name = name;
this.age = age;
this.hobit = hobit;
}
}
构造器的基本语法
修饰符 方法名 (形参列表){
方法体;
}
- 构造器的修饰符可以默认(就是什么都不写),也可以是public、protected、private
- 构造器没有返回值(不用写void)
- 方法名和类名的名字必须一样
- 在创建对象时,系统会自动的调用该类的构造器完成对象的初始化
- 一个类可以定义多个构造器,即构造器重载
- 如果我们没有定义构造器,系统会自动给类生成一个默认无参构造器(也叫默认构造器)
- 一旦定义了自己的构造器,默认的构造器就被覆盖了,就不能在使用默认的无参构造器,除非显示的定义一下。
演示系统的默认无参构造器
文章图片
我在Teacher这个类里面没有写构造器,看看利用javap反编译的结果
文章图片
从上面可以看到,系统默认给我们创建了一个无参构造器 ,只不过这里只声明了,所以Teacher()后面没有根{}。
显示定义无参构造器
People(){}
构造器里面什么都不写
this关键字在上面讲解构造器时,我们在写构造器的时候,构造器里面有一个关键字this。那this是什么,它有什么作用。
举个例子,现在有3个人,张三、李四、王五,它们分别编号1、2、3。它们被叫去办公室,第一个被叫去的是1,那么this就指代张三;第二个被叫去的是3,那么this就指代王五。
this关键字:this代表当前对象
演示this在内存中的情况
public class Test {
public static void main(String[] args) {
Dog dog = new Dog("哈巴狗", 3);
System.out.println("当前对象的哈希码值:"+dog.hashCode());
System.out.println("===================");
Dog dog1 = new Dog("财犬", 2);
System.out.println("当前对象的哈希码值:"+dog1.hashCode());
}
}
class Dog{
String name;
int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
System.out.println("当前对象的哈希码值:"+this.hashCode());
}
}
文章图片
文章图片
this关键字的细节
this关键字可以用来访问本类的属性、方法、构造器
public class Test {
public static void main(String[] args) {
Dog dog = new Dog();
}
}
class Dog{
String name = "李华";
int age = 20;
public Dog(){
this.eat();
}
public void eat(){
System.out.println("name = "+this.name+"age = "+this.age);
System.out.println("干了,兄弟们");
}
}
【JAVA|JAVA中的构造器和this关键字】
this用于区分全局变量和局部变量
public class Test {
public static void main(String[] args) {
Dog dog = new Dog();
}
}
class Dog{
String name = "李华";
int age = 20;
public Dog(){
this.eat();
}
public void eat(){
String name = "蔡徐坤";
System.out.println("name = "+name+"age = "+this.age);
System.out.println("干了,兄弟们");
}
}
文章图片
访问成员方法的语法:this.方法名(参数列表)
访问构造器语法:this(参数列表);注意只能在构造器中使用(即只能在构造器中访问另外一个构造器,必须放在第一条语句)
public class Test {
public static void main(String[] args) {
Dog dog = new Dog();
}
}
class Dog{
String name;
int age;
public Dog(){
this("哈密瓜",10);
System.out.println("你就笑吧");
}
public Dog(String name, int age) {
this.name = name;
this.age = age;
System.out.println("指定没你好果子吃");
}
}
文章图片
this不能在类定义的外部使用,只能在类定义的方法中使用
拓展 对象创建的流程分析以下面这个案例来分析
class Test{
public static void main(string[] args){
Person people = new Person("ikun",20);
}
}class Person{
int age = 999;
String name;
Person(String a,int b){
this.name = a;
this.age = b;
}
}
流程图:
文章图片
分析:
第一步:创建对象,在方法区里面加载Person类信息(包括属性信息、方法信息)
第二步:在堆区中为成员变量开辟空间,并且默认初始化(age默认初始化为0,name默认初始化为null)
第三步:显示初始化,将age初始化为999,name因为没有被赋值,所以还是null
第四步:调用构造方法,完成构造方法的初始化。age被初始化为20,name被初始化为ikun。
因为“ikun”是字符串常量,所以在方法区里面的常量池中,并返回一个地址给到堆区的name空间
第五步:将堆区中的地址返回给栈区的引用变量people
总结:
- 加载Person类信息
- 在堆区中分配空间
- 完成对象初始化
- 把对象在堆中的地址返回给person
JAVA中的作用域 分类:
全局变量:类中的属性就是全局变量,作用域为整个类体
局部变量:除了全局变量以外的其他变量,作用域为定义它的代码块中
演示全局变量和局部变量
public class Test{
public static void main(String[] args){}
}class People{
String name1 = "李华";
int age = 20;
String hobits = "唱,跳,rap,篮球";
public void say(){
int n1 = 100;
String name2 = "鸡";
System.out.println("全名制作人们,大家好,我是鸡鸡");
}public void modify(){
name1 = "蔡徐坤";
//这里是可以的,因为name1是全局变量,全局变量的作用域在整个类中
age = 3;
//这里是可以的,因为age是全局变量
System.out.println("姓名:+"name+"年龄:+"age);
}public void modefys(){
name2 = "ikun";
//这儿不可以会报错,因为name2是局部变量,局部变量的作用域只在它定义的代码块中
}}
全局变量和局部变量的注意事项
1.全局变量和局部变量可以重名,访问时遵循就近原则。
2.在同一个作用域中(比如同一个代码块、方法中),两个局部变量不能重名。
3.全局变量生命周期长,伴随着对象的创建而创建,伴随着对象的销毁而销毁。局部变量生命周期短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁。
4.全局变量可以在本类中使用,也可以在其他类中使用;局部变量只能在本类中对应的方法中使用
5.修饰符不同。全局变量可加可不加修饰符,局部变量不能加修饰符。
推荐阅读
- JAVA|反射机制和类加载机制
- 数据结构|Map和Set
- 开发语言|MYSQL 数据库 宋红康学习笔记
- Java|redis 发布和订阅 持久化 事务 缓存问题
- Java|使用两个注解,三步完成SpringBoot事件监听(反射,切面实现)
- Java|基于SpringBoot和Redis(Redisson的分布式锁的使用)
- java|一文了解配置中心
- java|SpringCloud笔记一( 跨模块调用,服务注册发现(Eureka、Nacos))
- redis|springboot整合spring @Cache和Redis