先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
正文
========================================================================
不论是从定义方法的语法来看,还是从方法的功能来看都不难发现方法和函数之间的相似性,实际上,方法确实是由传统的函数发展而来的,方法与传统的函数有着显著不同:
-
在结构化编程语言里,函数是一等公民,整个软件由 一个个的函数组成
-
在面向对象编程语言里,类才是一等公民,整个系统由一个个的类组成
在 Java 方法不能独立存在,方法必须属于类或对象,如果需要定义方法,则只能在类体内定义,不能独立定义个方法。
一旦将一个方法定义在某个类的类体内:
-
如果这个方法使用了 static修饰 ,则这个方法属于这个类,
-
如果没有使用static修饰则这个方法属于这个类的实例。
Java语言是静态的。一个类定义完成后,只要不再重新编译这个类文件,该类和该类的对象所拥有的方法是固定的,永远都不会改变。
方法不能独立存在,所以方法也不能像函数那样被独立执行,执行方法时必须使用类或对象来作为调用者 ,即所有方法都必须使用 类.方法 或 对象.方法 的形式来调用 。
这里可能产生 个问题: 同一个类里不同方法之间相互调用时,不就可以直接调用吗?这里需要指出:同 一个类的一个方法调用另外 个方时,如果被调方法是普通方法, 默认使用this 作为调用者;如果被调方法是静态方法,则默认使用类作为调用者。也就是说,表面上看起来某些方法可以被独立执行,但实际上还是使用 this 或者类来作为调用者。
方法属性总结:
-
方法不能独立定义,方法只 能在类体里定
-
从逻辑意义上来看,方法要么属于该类本身,要么属于该类 个对象
-
永远不能独立执行方法,执行方法必须使用类或对象作为调用者
使用 static 修饰的方法属于这个类本身,使用 static 修饰的方法既可以使用类作为调用者来调用,可以使用对象作为调用者来调用。但是因为使用 static 修饰方法还是属于这个类的,因此使用该类的任何对象来调用这个方法时将会得到相同的执行结果,这是由底层依然是使用这些实例所属的类作为调用者。没有 static 修饰的方法属于该类的对象,不属于这个类本身。因此没有 static 饰的方法只能使用对象作为调用者来调用,不能使用类作为调用者来调用 。使用不同对象作为调用者来调用同 一个普通方法,可能得到不同的结果。
===========================================================================
前面己经介绍了 Java 里的方法是不能独立存在的,调用方法也必须使用类或对象作为主调者果声明方法时包含了形参声明,则调用方法时必须给这些形参指定参数值,调用方法时实际传给形参的参数值也被称为实参。
那么, Java 的实参值是如何传入方法的呢?这是由 Java 方法的参数传递机制来控制的, Java 里方法参数传递方式只有一种值传递。所谓值传递,就是将实际参数值的副本(复制品)传入方法内,而参数本身不会受到任何影响。
Java 里的参数传递类似于《西游记》里的孙悟空,孙悟空复制个假孙悟空,这个假孙悟空具有和孙悟空相同的能力,可除以被砍头 但不管这个假孙悟空遇到什么事,孙悟空不会受到任何 与此类似,传入方法的是实际参数值的复制品,不管方法中对这个复制品如何操作,实际参数值本身不会受到任何影响。
方法参数传递效果实例
public class PrimitiveTransferTest {
public static void swap(int a, int b) {
// 下面三行代码实现 的值交换
// 定义一个临时变量来保存a的值
int tmp = a;
// a的值赋给b
a = b;
// 把临时变量 tmp的值赋给b
b = tmp;
System.out.println(“swap方法里,a的值是” + a + “; b的值是” + b);
}
public static void main(String[] args) {
int a = 6;
int b = 9;
swap(a, b);
System.out.println(“交换结束后,a变量 的值是” + a + "; b变量 的值是 " + b);
}
}
结果:
swap方法里,a的值是9; b的值是6
交换结束后,a变量 的值是6; b变量 的值是 9
从上面运行结果来看, swap()方法里 a和b的值是9、6 ,交换结束后,变量a、b的值依然是6、9 。
从这个运行结果可以看出 main()方法里的变量a和b并不是 wap()方法里的变量a和b。 swap()方法里的a和b只是main()方法里变量a和b的复制品。
实例程序的执行过程:
- Java 程序总是从 main()方法开始执行, main()方法开始定义了a、b两个局部变量
在内存中的存储示意图如图一所示
图一:main()方法中定义了a、b变量存储示意图
- 当程序执行 swap()方法时,系统进入 swap()方法,并将 main()方法中的变量a和b作为参数值传入swap()方法,传入swap()方法的只是a和b的副本,而不是a和b本身,进入 swap()方法后系统中产生了4个变量
在内存中的存储示意图如图二所示。
图二:main()方法中的变量作为参数值传入 swap()方法存储示意图
- 在main()方法中调用swap()方法时,main()方法还未结束。因此,系统分别为main()方法和swap()方法分配两块栈区,用于保存main()方法和swap()方法的局部变量。main()方法中的a、b变量作为参数值传入swap()方法,实际上是在swap()方法栈区中重新产生了两个变量a、b,并将main()方法栈区中a、 b变量的值分别赋给swap()方法栈区中的a、b参数(就是对swap()方法的a、b形参进行了初始化)。 此时,系统存在两个a变量、两个b变量,只是存在于不同的方法栈区中而已。程序在swap()方法栈区中交换a、b两个变量的值, 实际上是对图三中灰色覆盖区域的a、b变量进行 交换,交换结束后swap()方法中输出a、b变量的值,看到a的值为9, b的值为6,此时内存中的存储示意图如图三所示:
图三:swap()方法中a、b交换之后的存储示意图
对比图三与图一两个示意图中main()方法栈区中a、b的值并未有任何改变,程序改变的只是 swap()方法栈区中的a、b。
这就是值传递的实质: 当系统开始执行方法时,系统为形参执行初始化, 就是把实参变量的值赋给方法的形参变量,方法里操作的并不是实际的实参变量。
前面看到的是基本类型的参数传递,Java对于引用类型的参数传递,一样釆用的是值传递方式。下面程序示范了引用类型的参数传递的效果。
引用类型的参数传递实例
class DataWrap {
int a;
int b;
}
public class ReferenceTransferTest {
public static void swap(DataWrap dw) {
// 下面三行代码实现dw的a、b两个成员变量的值交换
//定义一个临时变量来保存dw对象的a成员变量的值
int tmp = dw.a;
// 把dw对象的b成员变量的值赋给a成员变量
dw.a = dw.b;
// 把临时变量tmp的值赋给dw对象的b成员变量
dw.b = tmp;
System.out.println(“swap方法里,a成员变量的值是” + dw.a + “; b成员变量的值是” + dw.b);
}
public static void main(String[] args) {
DataWrap dw = new DataWrap();
dw.a = 6;
dw.b = 9;
swap(dw);
System.out.println(“交换结束后,a成员变量的值是” + dw.a + “; b成员变量的值是” + dw.b);
}
}
结果:
swap方法里,a成员变量的值是9; b成员变量的值是6
交换结束后,a成员变量的值是9; b成员变量的值是6
从上面运行结果来看,在swap()方法里,a、b两个成员变量的值被交换成功。不仅如此,当swap() 方法执行结束后,main()方法里a、b两个成员变量的值也被交换了。这很容易造成一种错觉:调用swap() 方法时,传入swap()方法的就是dw对象本身,而不是它的复制品。
程序的执行过程:
- 程序从main()方法开始执行,main()方法开始创建了一个DataWrap对象,并定义了一个dw引用变量来指向DataWrap对象,这是一个与基本类型不同的地方。创建一个对象时,系统内存中有两个东西: 堆内存中保存了对象本身,栈内存中保存了引用该对象的引用变量。接着程序通过引用来操作DataWrap 对象,把该对象的a、b两个成员变量分别赋值为6、9。
此时系统内存中的存储示意图如图四所示。
图四:main()方法中创建了 DataWrap对象后存储示意图
- main()方法中开始调用swap()方法,main()方法并未结束,系统会分别为main()和swap() 开辟岀两个栈区,用于存放main()和swap()方法的局部变量。调用swap()方法时,dw变量作为实参传入swap()方法,同样釆用值传递方式:把main()方法里dw变量的值赋给swap()方法里的dw形参,从 而完成swap()方法的dw形参的初始化。值得指出的是,main()方法中的dw是一个引用(也就是一个 指针),它保存了 DataWrap对象的地址值,当把dw的值赋给swap()方法的dw形参后,即让swap()方 法的dw形参也保存这个地址值,即也会引用到堆内存中的DataWrap对象。
图五显示了 dw传入swap()后的存储示意图。
图五:main()方法中的 dw 传入 swap()方法后存储示意图
- 这种参数传递方式是不折不扣的值传递方式,系统一样复制了dw的副本传入swap() 方法,但关键在于dw只是一个引用变量,所以系统复制了 dw变量,但并未复制DataWrap对象。当程序在swap()方法中操作dw形参时,由于dw只是一个引用变量,故实际操作的还是堆内存中的DataWrap对象。此时,不管是操作main()方法里的dw变量,还是操作swap方法里的dw参数, 其实都是操作它所引用的DataWrap对象,它们操作的是同一个对象。因此,当swap()方法中交换dw 参数所引用DataWrap对象的a、b两个成员变量的值后,可以看到main()方法中dw变量所引用DataWrap 对象的a、b两个成员变量的值也被交换了。
为了更好地证明main()方法中的dw()和swap()方法中的dw是两个变量,在swap()方法的最后一行增加如下代码:
//把dw直接赋值为null,让它不再指向任何有效地址
dw = null;
执行上面代码的结果是swap()方法中的dw变量不再指向任何有效内存,程序其他地方不做任何修改。main()方法调用了 swap()方法后,再次访问dw()变量的a、b两个成员变量,依然可以输出9、6。 可见main()方法中的dw变量没有受到任何影响。实际上,当swap()方法中增加dw = null代码后,内存中的存储示意图如图五所不。
图五:将swap()方法的 dw 赋值为 null 后存储示意图
从图五来看,把swap()方法中的dw赋值为null后,swap()方法中失去了DataWrap的引用,不可再访问堆内存中的DataWraper对象。但main()方法中的dw变量不受任何影响,依然引用DataWrap对象,所以依然可以输岀DataWrap对象的a、b成员变量的值。
======================================================================
JDK 1.5 开始,Java支持传递同类型的可变参数给一个方法。
方法的可变参数的声明如下所示:
typeName… parameterName
最后
光给面试题不给答案不是我的风格。这里面的面试题也只是凤毛麟角,还有答案的话会极大的增加文章的篇幅,减少文章的可读性
Java面试宝典2021版
最常见Java面试题解析(2021最新版)
2021企业Java面试题精选
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
899792)]
最常见Java面试题解析(2021最新版)
[外链图片转存中…(img-2DVhVw7E-1713251899793)]
[外链图片转存中…(img-P2yHGy4Y-1713251899793)]
2021企业Java面试题精选
[外链图片转存中…(img-oYNLV4o9-1713251899793)]
[外链图片转存中…(img-BcZPWRQ3-1713251899794)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-6913Cz69-1713251899794)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!