前言❤️❤️
hello hello💕,这里是洋不写bug~😄,欢迎大家点赞👍👍,关注😍😍,收藏🌹🌹
这篇文章大部分是一些相对比较基础的内容,像构造方法,重写方法这些,这些知识可能有一点点抽象,还是需要后面多练习,才能更好的掌握
这篇文章就是不停的删一些代码,再加上一些代码,然后看效果,强烈建议初学的铁汁们有时间敲一下代码🐵🐵🐵
🎇个人主页:洋不写bug的博客
🎇所属专栏:Java学习之旅,从入门到进阶
🎇铁汁们对于Java的各种常用核心语法(不太常用的也有😆),都可以在上面的Java专栏学习,专栏正在持续更新中🐵🐵,有问题可以写在评论区或者私信我哦~
1,Set方法
1,基础讲解
这里写一个Date(日期)类,这里要给Date这个类里面的变量赋值的话,就需要一个一个写,就有点麻烦
public class Date {
public int year;//成员变量是紫色的
public int month;
public int day;
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
public static void main(String[] args) {
Date date = new Date();
date.year = 2025;
date.month = 8;
date.day = 6;
date.printDate();
}
}
那就可以有跟变量赋值的这样一个方法,一下子给所需变量赋值完
就可以写一个setDate方法加进去🐵
通过创建的date对象来调用这个方法,就能够对类中的变量进行设定了,就很方便
public class Date {
public int year;//成员变量是紫色的
public int month;
public int day;
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
public void setDate(int y,int m,int d){
year = y;
month = m;
day = d;
}
public static void main(String[] args) {
Date date = new Date();
date.setDate(2025,8,6);
date.printDate();
}
}
2,this关键字
那如果这样写setDate方法,有没有问题呢?
public void setDate(int year ,int month,int day){
year = year;
month = month;
day = day;
}
这个其实都不用通过运行来判断有没有出错,只需要写完看一下代码就可以了
我们知道,成员变量颜色是紫的(赋值或者使用的前提下),但是这个就不是紫的,说明系统把这个year,month,day当成形参了,这里就是赋值失败了
形参就是public void setDate(int year ,int month,int day)括号里的参数

运行一下发现确实是赋值失败了‘

为了解决这个问题,系统是这样规定的,在成员变量前加this
这样即使名字相同,成员变量前有this.,形参前面没有,系统就很容易能够区分出来
这里只需要输入一个this.,后面IDEA会给出选项,我们按一下enter键就可以了,非常方便。

加上this以后就发现正常了,这里前面是成员变量,颜色是紫色,后面是形参

注:这里如果形参的名字跟成员变量设置的不一样(比如第一种写法,year的形参设成y),那么不写this是完全可以的,完全看个人喜好,这里我们理解即可,后面都是直接用系统直接生成的,不需要自己写(后文中会提到)
this引用的几个特征:
①:哪个对象调用的方法,this就指向的是哪个对象
这个其实很好理解,前面是date这个对象调用的set方法,那么this指向的对象当然就是 date这个对象,故this.year指的就是 date这个对象的成员变量

②:this只能在成员方法中使用
在Java中,方法分为成员方法,和静态方法,静态方法就是加了static的,成员方法就是不加static的,具体的区别后面会提到
大家可以尝试一下,在setDate方法中,在public和void之间加一个static,那么立马就会报错(如下图),报错原因就是this不能用于static方法中

③在成员方法中,this只能指向调用方法的对象(可以结合①来理解),不能在方法中强行修改,指向别的对象
以下图代码为例,在方法中,如果新创建一个对象,让this指向这个对象,也是不行的。(这个了解一下语法规则即可,我感觉铁汁们也不会这样做)
2,构造方法
1,默认构造方法
构造方法,就是构造对象时的方法
那前面的Date类没有写构造方法,那为什么能创建对象而不报错呢?

这是因为当我们写类的时候,会自动有一个默认的构造方法(这个构造方法是空的,它的作用就是调用时能创建对象),并不会显示出来,下面这个代码就是默认构造方法
public Date(){
}
那可能大家看到这就懵逼了,会想:你这不是忽悠我的吗,你前面说方法就是C语言中的函数,那这一个空的函数,怎么就创建出对象了🙄?
其实大家可以这样理解,那就是这个空的方法的核心作用就对数据进行初始化(比如前面将year,month,day这些变量都初始化为0)
注:分配空间其实靠的并不是这个默认的构造方法,而是JVM在检测到这个new关键字时,就会自动在堆内存中分配空间,接着调用这个默认构造方法进行初始化(因为触发了一系列流程,这里我们先不用理解)
一句话总结,其实在调用构造方法前JVM就已经为对象在堆中分配空间了,调用这个构造方法只是为了给对象的成员变量进行初始化
2,自定义构造方法(方法重载)
这里要创建对象,还要再用set方法来设置对象里面的数据
那能不能更简单,只用一行代码,就做到创建对象和设置成员变量数据的结合

要实现一行代码,就做到创建对象和设置成员变量数据,那就要使用自定义构造方法(这里刚学可能会有点抽象,下面的概念如果理解不了,就先往后看代码,看完再回来看概念)
前面说默认构造方法就是把对象进行初始化,那就可以在构造方法里面加一点东西,给对象的变量赋值,或者让我们直接可以在构造方法里面传参数,进而直接给变量赋值。
1,无参
这里废话不多说,就直接上代码:
这里写了两个自定义的构造方法,那可能有的铁汁就会比较奇怪,为什么这里两个方法名字相同,却不会报错呢?
大家别忘了我们前面讲到过的方法重载,这两个方法一个是有参,一个是无参的
public class Date {
public int year;//成员变量是紫色的
public int month;
public int day;
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
public void setDate(int year ,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
public Date(){
year = 2025;
month = 8;
day = 6;
System.out.println("调用自己写的构造方法");
}
public Date(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
System.out.println("调用自己写的构造方法");
}
public static void main(String[] args) {
Date date = new Date();
date.printDate();
}
}
那这里铁汁们思考一个问题,在这段代码在main函数中创建一个对象,不往里面传参
那么调用的到底是默认的无参构造方法,给所有变量的值都初始化为0;还是新定义的这个无参构造方法呢???
这里敲一下代码,再运行一下清楚了

执行的是新定义的这个构造方法
实际上,默认无参构造方法只有在我们没有写无参构造方法时才会自动调用,如果我们写了,编译器其实就不再生成了
2,有参
在Set方法部分举例的这个代码,定义一个对象,并且给对象中的变量赋值,需要两步
有了有参构造方法之后,一步就可以了

直接在括号里面写参数,即可调用有参构造方法
public class Date {
public int year;//成员变量是紫色的
public int month;
public int day;
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
public void setDate(int year ,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
public Date(){
year = 2025;
month = 8;
day = 6;
System.out.println("调用自己写的无参构造方法");
}
public Date(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
System.out.println("调用自己写的有参构造方法");
}
public static void main(String[] args) {
Date date = new Date(2025,8,6);
date.printDate();
}
}

3,构造方法特点
构造方法有以下六大特点:
①:构造方法的名字必须与类名相同
创建对象时,右面new的是类名,如果写的构造方法名字跟类名不同,那编译器就找不到构造方法了

②构造方法是没有返回值类型的,连void都不能写
在学类之前见到的方法就是没有返回值类型就写void,但是在构造方法这里是不行的,中间什么都不要写
写了void之后,系统就把这个方法理解为普通的方法了,而不是构造方法,在创建对象时也就不会调用。
原因:
构造方法并不是普通的方法,它的本质就是初始化对象(对象中的变量),而且它的调用是在创建对象时调用的,那么如果是普通的void构造方法,想调用的话就直接写方法就行了
普通方法是通过对象名.方法来调用的,也就是对象调用的;但是构造方法是JVM去调用的
综上,可以理解为普通方法和构造方法就不是一个东西
③创建对象时编译器自动调用构造方法,并且,创建一个对象只能调用一次构造方法
一种更专业的说法就是在这个对象的生命周期中只调用一次构造方法(生命周期就是从开始创建到销毁这段时间)
④构造方法可以根据自己的需要来重载,这个前面也举过例子了,像有参的构造方法,参数的个数也可以不同,这些都是方法重载。
⑤如果用户没有写构造方法,那就会自动调用编译器默认的构造方法,这个构造方法是无参的’
⑥一旦用户定义了自己的(不管有参无参)构造方法,那么编译器就不再生成了。
注:如果我们只定义了有参的构造方法,但是创建对象时还是用无参来创建的,那么就不会调用默认构造方法,这里会报错!下面这个代码就是报错的。
public class Date {
public int year;//成员变量是紫色的
public int month;
public int day;
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
public void setDate(int year ,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
public Date(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
System.out.println("调用自己写的有参构造方法");
}
public static void main(String[] args) {
Date date = new Date();
date.printDate();
}
}

4,构造方法的相互调用
1,内容讲解
构造方法的相互调用指的是在一个构造方法的第一句中用this(); 调用其他的构造方法
在下面这段代码中,我们只看两个构造方法,在无参构造方法中的第一句加上this.(2025,8,7),调用有参构造方法
public class Date {
public int year;//成员变量是紫色的
public int month;
public int day;
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
public void setDate(int year ,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
public Date(){
this(2025,8,7);
System.out.println("调用自己写的无参构造方法");
}
public Date(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
System.out.println("调用自己写的有参构造方法");
}
public static void main(String[] args) {
Date date = new Date();
date.printDate();
}
}

在main方法中用的无参构造方法来创建对象
那就是走到无参方法的第一句this(2025,8,7);时,就进入了有参构造方法中,接着执行完有参构造方法,再执行无参构造方法下面的打印语句
注:
①这里的this只能放到构造方法的第一句,否则IDEA就会报错,提示我们把this放到第一句

②另外方法的相互调用不能形成循环
如果在无参构造方法中用this加参数调用有参构造方法,在有参构造方法中用this调不加参数用无参构造方法,那这不就成死循环了,肯定就会报错
2,查看源代码
查看源代码可以方便对于代码的理解,特别是在这里相互调用的时候
按住ctrl键,再点击无参构造方法第一句的this,这时候this下面就有个下划线,点击一下,就跳到了有参构造方法中
这说明这个this就是跳到有参构造方法中去执行的

也可以用同样的方法,按住ctrl键,点击一下println,跳转进去的界面就是println的源码定义处,后面学习时会看一些字符的源码来方便理解

5,经典例题
题目要求是找出这段代码中错误的地方,铁汁们可以试着找一下🐵
这道题博主学的时候老是做错,主要还是概念不太理解😅


一共有两个错误:
①:前面说了,如果自己定义了构造方法的话,那么系统就不会再生成默认的无参构造方法了,因此还需要自己再写一个,那这里没有写,这里就会出错。
②:这个就很简单了,我们的有参构造方法有两个参数,但是只传入了一个,这里当然会报错。
3,三种初始化的执行顺序
除了构造方法初始化对象外,还有就地初始化和代码块初始化,但是这两种初始化使用的并不多
但是还是要学习一下,起码保证未来别人这样写代码我们能看懂
1,就地初始化
所谓就地初始化,就是简单粗暴,定义时直接给成员变量赋值,示例如下:
public class Date {
public int year = 2025;//成员变量是紫色的
public int month = 8;
public int day = 7;
2,代码块初始化
代码块就是用大括号{ }围住的一个代码片段。
那所谓的代码块初始化,就是在类中写一个大括号,在里面对成员变量进行初始化
示例如下,打印后日期就是2025-8-7。
public class Date {
public int year;//成员变量是紫色的
public int month;
public int day;
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
{
year = 2025;
month = 8;
day = 7;
}
public static void main(String[] args) {
Date date = new Date();
date.printDate();
}
}
3,执行顺序
执行的顺序:
1,就地初始化
2,代码块初始化
3,构造方法初始化
后执行的会把前面的结果给覆盖掉。
就地初始化是在成员变量定义的时候就初始化了,那么肯定是最先执行,这个我们就不用验证了,那就验证一下剩下两个的执行顺序
我们看一下这段代码,在代码块中初始化的年份的值是2024,在构造方法中对年份的初始化是2025,
public class Date {
public int year;//成员变量是紫色的
public int month;
public int day;
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
{
year = 2024;
month = 8;
day = 7;
System.out.println("执行构造代码块");
}
public Date(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
System.out.println("调用自己写的有参构造方法");
}
public static void main(String[] args) {
Date date = new Date(2025,8,7);
date.printDate();
}
}
看一下运行结果,就能够发现是构造方法初始化的赋值把代码块初始化赋值给覆盖了,因此构造方法初始化是排最后的

4,对象的打印(方法重写)
我们上来直接去打印对象,那么结果就是一段hashCode(后面的内容,这里先不用管)
public static void main(String[] args) {
Date date = new Date();
System.out.println(date);
}

如果想打印对象时能打印出对象中变量的信息,应该怎么搞呢?
其实,用println打印对象时,自动调用了默认的toString()方法
我们自己写一个toString方法,把系统默认的换掉就行了,那这种替换老方法的操作,就是方法重写
这里重写toString时,方法是写到Date类里的,有返回值类型,是一个字符串String类型
public class Date {
public int year;//成员变量是紫色的
public int month;
public int day;
public Date(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
public String toString(){
return "年份:" + year + "\n月份:" + month + "\n日:" + day;
}
public static void main(String[] args) {
Date date = new Date(2025,8,7);
System.out.println(date);
}
}
有个问题,重写toString方法的时候是加不加static,接下来分析一下:
- 方法前加了static是静态方法,不加static是实例方法
静态方法有个特点,那就是不能进行方法重写,而实例方法可以
这里的toString都可以方法重写了,那就一定是实例方法,不能加static 这里方法重写完以后,会发现方法左边有个这样的标志,这就是方法重写的标志,点击这个标志,就回到了重写替换的源代码上


另外,在方法重写时,要在重写方法上面加上一个@Override,表示这个方法是重写的
- 不写@Override也不会报错,加上@Override,是对方法/类的补充说明,加了这样的补充说明后,编译器就会对这个方法/类进行更加严格的语法检查,确保我们不出错。

整体代码如下:
public class Date { public int year;//成员变量是紫色的 public int month; public int day; public Date(int year,int month,int day){ this.year = year; this.month = month; this.day = day; } @Override public String toString(){ return "年份:" + year + "\n月份:" + month + "\n日:" + day; } public static void main(String[] args) { Date date = new Date(2025,8,7); System.out.println(date); } }这时候打印对象,就直接调用自己写的toString方法

方法重写和重载的辨析:
- 方法重写:方法重写就是许多方法可以方法名相同,但是参数列表(括号里面定义的形参)不能相同,在调用时编译器根据传入的参数来判断到底调用哪个方法。
- 方法重载:方法重载就是写一个方法去替代原有的方法(后面我们学习继承时会大量使用方法重写),重新写一个跟这个方法名字相同的方法,下次执行时新写的方法就把原来的方法顶掉了,执行新写的方法
5,代码自动生成
IDEA是可以自动生成这些Set,还有有参无参构造方法的,刚开始学习可以自己写
在熟练掌握以后,就直接用系统生成即可这里定义好一个类,Set,构造方法什么都不写:
public class Date { public int year;//成员变量是紫色的 public int month; public int day; public void printDate(){ System.out.println(year + "-" + month + "-" + day); } public static void main(String[] args) { Date date = new Date(); date.printDate(); } }然后按alt(台式机键盘或者笔记本加外设键盘就是按alter键) + insert键,就会有这么多的选项(这里面其他选项的方法后面在后面的博客的内容中)

比如要生成构造方法,就点击Constructor,里面是成员变量供我们选择、
按住ctrl键,可以选择多个成员变量创建有参构造方法
三个成员变量都选中,这时候就生成了一个有三个参数的构造方法。

需要生成无参的构造方法,就点击下面的Select None,就能直接生成

生成Set也是如此,我们alt + enter键,点击Setter,选择成员变量,也可以生成Set方法,选择3个成员变量,就生成了三个set方法:


点击在类中重写toString方法,系统会自动生成一段代码,一般需要根据自己的实际需要对返回值进行修改,总体来说是比自己写要简单的


6,用包来管理代码和包的导入
1,包的管理
在src中new,创建出一个pacakage(包),在命名包时英文字母开头一般都是小写
例如现在在学习类和对象,就创建一个名为object的包
后面练习代码时,直接在这个object包中去创建类(右键点击包,然后创建类即可,类的首字母一般是大写),这样我们找以前写过的代码也特别清楚,下图就是在包中去创建类

铁汁们可以看一下博主这里JavaSE的包分类,分为数组,异常,方法,类和对象,String类等等,这样以后找以前写过的代码就会很轻松

建议还没给代码分类的铁汁现在也根据代码的内容创建一些包,按照代码内容的不同放在不同的包中(在包外写的类也可以用鼠标拖动到包中)。
一个包其实就是一个文件夹,而编程时文件夹的术语是“目录”,这样叫就能显得的我们更专业一些,创建包其实就是创建目录,把有关联关系的类,放到目录里面去。

另外,在包中创建类,类的最上面会自动加上包名
下图就是博主在csdn包中创建的Date类。
2,包的导入
用包来管理代码是很方便的,别人写的代码也会用包来组织起来。
我们想要使用别人的代码,就需要在当前我们的代码中,导入别人的包例如使用Scanner的时候,IDEA就会在上面自动导入util包中的Scanner类,这个实际上导入的是一个类
在日常开发中,无论是导入整个包,还是只导入包中的一个类来使用,都习惯称为导入包

由于这个是IDEA自动生成的,所以我们对这个感觉可能不是很明显,有时候偶尔IDEA出bug,没有自动添加的话,我们也可以alt + enter进行添加

还有这样的一种包导入,就是把所有包都导进去。
这就是一个万金油,但是这样并不好
把有用的,没用的都导入进去,其实是会影响效率,还有其他很多潜在的问题import java.util.*; public class Date { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); Random random = new Random(); } }7,代码存储的查看
例如需要查看Date类的存储位置。
右键这个类,点击Open in,再点击Explore,即可打开代码存储位置。
这里就打开了.java文件的存储位置

同时,也可以用同样的方法打开包这个目录(文件夹的专业讲法)的存储位置


结语💕💕
在练习一些题目觉得抽象是很正常的,这部分的所有知识占了JavaSE将近一半的内容,想初学一下子掌握透是有点困难的,还是要多写代码去练习
🥳🥳大家都学废了吗?完结撒花~ 🎉🎉🎉




483

被折叠的 条评论
为什么被折叠?



