byte b1 = 2;
//byte c1 = a1 + b1;//会报错,大转小
byte c1 = (byte) (a1 + b1);//强制类型转换就不会报错了
System.out.println(c1);//3
byte d1 = (byte) 128;
System.out.println(d1);//-128,强制类型转换要在小类型的范围内转,否则会发生数据溢出的问题
short e1 = ‘a’;
char f1 = 120;
System.out.println(e1);//97
System.out.println(f1);//‘x’
float h1 = 32874.456f;
int i1 = (int) h1;
System.out.println(i1);//32874
}
}
9.运算符
-
普通的四则运算符 + - * / ,普通的四则运算,并不能直接改变变量本身的值,除非 i = i*10+8
-
取余 % 6%4=2 6%3=0(余数为0表示整除)
-
自增自减运算符
1)可以改变变量本身的值
2)前缀式: 符号在前,先改变变量本身的值(+1/-1),再使用(打印/参与运算…)
3)后缀式: 符号在后,先使用(打印/参与运算…),再改变变量本身的值(+1/-1)
4)注意:不管是前缀式还是后缀式,一定是会改变变量本身的值,区别在于执行的时机不同
-
比较运算符
-
比较运算符最终的结果是布尔类型的
-
== 比较的是左右两边的值是否相等 !=比较的是左右两边的值是否不相等
-
练习题:==比较的练习
package cn.tedu.basic;
/本类用于测试运算符/
public class TestOperator {
public static void main(String[] args) {
//创建小猫类的对象
Cat c1 = new Cat();
Cat c2 = new Cat();
int[] a1 = {1,2,3};
int[] a2 = {1,2,3};
int b1 = 4;
int b2 = 4;
boolean f1 = true;
boolean f2 = true;
/==如果比较的是引用类型,比较的值是引用类型变量保存的地址值/
System.out.println(c1 == c2);//false
System.out.println(a1 == a2);//false
/==如果比较的是基本类型,比较的值就是字面值,也就是这个变量具体存的那个数/
System.out.println(b1 == b2);//true
System.out.println(f1 == f2);//true
}
}
class Cat{
String name;
int age;
public void bark(){
System.out.println(“喵喵叫”);
}
}
- 逻辑运算符
双与/短路与/&& :
判断逻辑与&一致,增加了短路的功能全真才真,有假则假
双或/短路或/|| :
判断逻辑与|一致,增加了短路的功能全假才假,有真则真
注意:我们这里所说的短路,是指在某些情况下,表达式后半部分就不用计算了,因为我们已经知道了结果,也就是被短路了,短路可以提高程序的性能,但是短路不一定会用到
-
三目运算符: 1 ? 2 : 3; 1是表达式,1真取2,1假取3
-
复合赋值运算符:+= -= *= /=是一种简写的形式,比较方便,运算时会自动进行类型转换
-
赋值运算符: = ,右边给左边
-
拼接功能:+
-
位运算符 : 主要参与的是二进制的运算
&与:全真才真
| 或:全假才假
-
^异或:相同为0 不同为1
- 非: 非0为1,非1为0
-
优先级控制:如果表达式的运算比较复杂,需要控制优先级,可以使用小括号
-
拓展:instanceof
10.流程控制
1.顺序结构
顺序结构中的代码会按照顺序一行一行向下执行所有的代码语句,可以用来进行输入 输出 计算等的操作
但顺序结构不可以完成先做判断,再做选择的流程
2.分支结构
- 单分支结构
if(判断条件){
如果判断条件的结果为true,就执行此处代码,不符合条件,此处跳过
}
- 多分支结构
if(判断条件){
如果判断条件的结果为true,就执行此处的代码
}else{
如果不符合条件,执行else处的代码
}
- 嵌套分支结构
if(判断条件1){
符合判断条件1,执行此处代码,不符合,继续向下判断
}else if(判断条件2){
符合判断条件2,执行此处代码,不符合,继续向下判断
}else if(判断条件3){
符合判断条件3,执行此处代码,不符合,继续向下判断
}else{
保底选项,以上条件均不符合的情况下,执行此处代码
}
4.练习:
package cn.tedu.basic;
import java.util.Scanner;
/本类用于复习分支结构/
public class TestIf {
public static void main(String[] args) {
//1.提示并接收用户输入的月份
System.out.println(“请输入您要测试的月份:”);
int month = new Scanner(System.in).nextInt();
//2.对用户输入的数据进行判断
if(month<=0 || month >12){
System.out.println(“您输入的数据不正确!”);
}else{
//3.如果用户输入的数据正确,我们就进行季节的判断
if(month >=3 && month <=5){
System.out.println(month+“月是春天”);
}else if(month >=6 && month <=8){
System.out.println(month+“月是夏天”);
}else if(month >=9 && month<=11){
System.out.println(month+“月是秋天”);
}else{
System.out.println(“冬天就要来啦,春天还会远吗?”);
}
}
}
}
3.选择结构
- 小括号中变量支持的类型:
byte short char int String enum 与4个基本类型对应的包装类
-
注意: 如果配置了default默认选项,而且没有任何的case被匹配到,就会执行default这个“保底选项”
-
case的个数 是否加break 是否加default全部都是可选的,根据自己的具体业务做决定
-
小括号中变量的类型必须与case后value的类型一致
-
执行顺序:先拿着变量的值,依次与每个case后的值做比较,如果相等,就执行case后的语句
若这个case后没有break,就会继续向下执行下一个case,如果一直没有遇到break,就会发生穿透现象,包括default
switch (变量名){
case value1 : 操作1;break;//可选
case value2 : 操作2;break;//可选
case value3 : 操作3;break;//可选
case value4 : 操作4;break;//可选
default:保底选项;//可选
}
4.循环结构
可以帮我们多次重复的做某一件事
1.for循环
for(开始条件;循环条件;更改条件){
如果符合循环条件,就会执行循环体里的内容
}
注意1:写法小窍门:从哪开始 到哪结束 循环变量如何变化
注意2:for循环能够执行多少次,取决于循环变量可以取到几个值
2.嵌套for循环
外层循环控制的是轮数,内层循环控制的是每一轮中执行的次数
对于图形而言,外层循环控制的是行数,内层循环控制的是列数
for(开始条件;循环条件;更改条件){//外层循环
for(开始条件;循环条件;更改条件){//内层循环
循环体
}
}
注意:外层循环控制的是行数,内层循环控制的是列数
注意:外层循环控制的是轮数,内层循环控制的是在这一轮中执行的次数
3.高效for循环
for(遍历到的元素的类型 遍历到的元素的名字 :要遍历的数组/集合名){
循环体
}
优点:写法简单,效率高
缺点:只能从头到尾的遍历数据,不能进行步长的选择
4.while循环
while(判断条件){
如果符合判断条件,继续循环
}
注意:常用来完成死循环,但死循环必须设置出口!
练习题:while循环练习
package cn.tedu.basic;
/本类用于复习while循环/
public class TestWhile {
public static void main(String[] args) {
//需求:通过while循环打印10次"小可爱们中午好~"
//f1();
//需求:通过while循环打印1 2 3 … 10
//f2();
//需求:通过while循环打印1 3 5 7… 99
f3();
//需求:通过while计算1+2+3+4…+10
f4();
//需求:通过while计算2+4+6+8…+100
f5();
}
private static void f5() {
//需求:通过while计算2+4+6+8…+100
int i = 2;//定义循环变量i用来控制循环
int sum = 0;//定义变量用来保存累加的结果
while (i<=100){
//sum += i;
sum = sum + i;//累加
//i += 2;
i = i + 2;//循环变量i每次+2
}
System.out.println(“2到100所有偶数的和为:”+sum);
}
private static void f4() {
//需求:通过while计算1+2+3+4…+10
int i = 1;//用于控制循环,相当于循环变量
int sum = 0;//用于保存求和累加的结果
while(i<=10){
sum = sum + i;
i++;
}
System.out.println(“1到10累加的结果为:”+sum);
}
private static void f3() {
//需求:通过while循环打印1 3 5 7… 99
int sum = 1;
while(sum <100){
System.out.println(sum);
//sum = sum +2;
sum += 2;
}
}
private static void f2() {
//需求:通过while循环打印1 2 3 … 10
//1.定义一个变量来控制执行的次数
int i = 1;
while(i<=10){
System.out.println(i);
i++;
}
}
private static void f1() {
//需求:通过while循环打印10次"小可爱们中午好~"
//1.定义一个变量用来控制执行的次数
int count = 1;
while(count <= 10){
System.out.println(“小可爱们中午好~”);
count++;//注意count的值需要自增,否则还是一个死循环
}
}
}
5.do-while循环
do-while循环一定会执行一次,然后再判断,如果符合条件,再执行后面的循环
do{
循环体
}while(判断条件);
循环之间的比较
-
如果明确知道循环的次数/需要设置循环变量的变化情况时–使用for循环
-
如果想写死循环–while(true){}
-
如果需要先执行一次,再做判断–do-while循环
-
循环之间是可以互相替换的,但是最好使用比较合适的循环结构
11. 方法
-
格式: 修饰符 返回值类型 方法名(参数列表){ 方法体 }
-
如何确定我们要调用哪个方法呢?方法名+参数列表
-
一个方法被调用,就会执行这个方法的功能,执行完毕就返回到方法被调用的位置,在第几行调用,程序就返回到第几行继续向下执行
如果这个方法有返回值,我们有两种选择:
-
选择只执行功能,不接收返回值,不再继续使用这个方法的结果
-
选择在方法调用的位置接收这个方法的返回值,接收到的返回值可以在方法外继续使用
-
方法的重载:
在同一个类中出现多个方法名相同,但参数列表不同的方法
注意:方法是否构成重载,取决于参数列表中参数的个数与参数的类型,与参数的名字无关
重载的意义: 重载不是为了程序员方便,而是为了方便外界调用这个名字的方法时,不管传入什么类型的参数,都可以匹配到对应的方法来执行,程序会更加的灵活
- 方法的传值 : 如果方法的参数类型是基本类型,传入的是实际的字面值,如果是引用类型,传入的是地址值
形参:形式意义上的参数,比如方法参数列表的参数名,光看参数名是无法确定这个变量的值是多少的
实参:实际意义上的参数,比如我们的局部变量,比如成员变量,比如调用方法时传入的数字
- 方法的重写: 子类继承了父类以后,想要在不改变父类代码的情况下,实现功能的修改与拓展
重写遵循的规则:两同 两小 一大
一大: 子类方法的修饰符权限 >= 父类方法的修饰符权限
两同: 方法名与参数列表与父类方法保持一致
两小: 子类方法的返回值类型 <= 父类方法的返回值类型,注意:这里的<=说的是继承关系,不是值的大小
子类方法抛出的异常类型 <= 父类方法抛出的异常类型
- 四种权限修饰符
8.练习题:方法调用的顺序
package cn.tedu.basic;
/本类用于测试方法的调用/
public class MethodDemo {
//1.创建程序的入口函数main()
public static void main(String[] args) {
System.out.println(“main() start…”);
m1();
System.out.println(“main() stop…”);
int a =5;
System.out.println(a);
}
//2.创建m1()
private static void m1() {
System.out.println(“m1() start…”);
m2();
System.out.println(“m1() stop…”);
}
private static void m2() {
System.out.println(“m2() start…”);
}
}
9.拓展 : 方法的递归
12. 数组
- 数组的创建方式:
静态创建 int[] a = {1,2,3,4,5};
静态创建 int[] a = new int[]{1,2,3,4,5};
动态创建 int[] a = new int[5]; 后续可以动态的给数组中的元素赋值
注意:不管是什么样的创建方式,都需要指定数组的类型与长度
- 我们可以通过数组的下标来操作数组中的元素
数组下标从0开始,最大下标是数组的长度-1,如果访问到了不是这个数组的下标,会出现数组下标越界异常
比如:a[5]表示的就是数组中的第6个元素
-
数组的长度:数组一旦创建,长度不可改变,长度指的是数组中元素的个数a.length,并且数组的长度允许为0:[ ]
-
数组的创建过程:
-
根据数组的类型与长度开辟一块连续的内存空间
-
对数组中的每个元素进行初始化,比如int数组的默认值就是0
-
生成数组唯一的一个地址值,交给应用类型变量a来保存
-
后续可以根据数组的下标再来操作数组中的具体元素
注意: 数组名a这个变量,保存的是数组的地址,不是数组中的具体元素
-
数组的工具类Arrays
-
toString(数组名) : 除了char类型的数组以外,其他类型的数组想要查看具体元素,需要使用本方法,否则打印的是地址值
-
copyOf(原数组名,新数组的长度) : 用来实现数组的复制 扩容 缩容
如果新数组的长度 > 原数组长度,就扩容,反之,则缩容,如果两者长度一致,就是普通的复制数组
注意:一定是创建了新数组,而不是对原数组的长度做操作
- 数组的遍历
一般习惯使用for循环,循环变量代表的就是数组的下标,从0开始,最大值是a.length-1
- 冒泡排序 :
外层循环控制比较的轮数,所以循环变量从1到n-1轮,代表的是轮数
内层循环控制的是这一轮中比较的次数,而且是数组中两个相邻元素的比较,所以循环变量代表的是数组的下标
8.练习:
package cn.tedu.basic;
/本类用于复习数组的操作/
public class TestArray {
public static void main(String[] args) {
//需求1:求出数组中所有元素之和
//f1();
//需求2:求出数组中所有元素的最大值
f2();
}
private static void f2() {
//需求2:求出数组中所有元素的最大值
//1.定义一个数组
int[] a = {10,20,98,40,55};
//2.定义一个变量,用来存储结果,也就是数组中所有元素的最大值
int max = a[0];//这个位置不能写0,应该是数组中的第一个元素
//3.遍历数组,依次拿出数组中的每一个元素与之前设定的元素做比较
for (int i = 0; i < a.length; i++) {
//4.判断当前遍历到的元素,与max谁大
if(a[i]>max){//如果当前遍历到的元素比max大
max = a[i];//就把遍历到的这个元素的值赋值给max
}
}
//5.循环结束,输出数组中最大的值
System.out.println(“数组中的最大值为:”+max);
}
private static void f1() {
//需求1:求出数组中所有元素之和
//1.定义一个数组
int[] a = {12,12,22,22,22};
//2.定义一个变量,用来保存最终求和的结果
int sum = 0;
//3.通过数组的遍历,遍历数组中的每一个元素,然后累加
for (int i = 0; i < a.length; i++) {
sum = sum + a[i];
}
System.out.println(“数组累加所有元素之和为:”+sum);
}
}
===============================================================================
1.面向对象与面向过程
-
两者都是一种编程的思想
-
面向对象强调的是事情的结果,我们通过对象完成对应的功能
-
面向过程强调的是事情的过程,我们做任何事情,都要亲力亲为,经过每一个步骤
-
Java是一门面向对象的语言
2.类与对象
-
定义类通过关键字class来定义,类是一类事物的抽象,它是抽象的,它是模板
-
创建对象通过new关键字触发构造函数生成,对象是根据类创建出来的具体的内容
-
一个类可以创建出多个对象,对象是根据类的设计来创建的,所以对象具有类的所有属性与功能
-
对象之间是相互独立的,互不影响。我们把创建对象也称作“实例化”
3.面向对象的三大特性:封装
-
前提:为了保证数据的安全,也为了程序的使用者能够按照我们预先设计好的方式来使用资源
-
封装属性:用private修饰我们的属性
然后为属性提供对应的getXxx()【获取属性值】与setXxx()【设置属性值】
- 封装方法:用private修饰方法,被修饰的方法只能在本类中使用,所以我们在本类的公共方法里调用这个私有方法
外界如果想要使用这个私有方法的功能,只需要调用这个公共方法就可以了
4.面向对象的三大特性:继承
-
前提 :继承可以实现程序的复用性,减少代码的冗余
-
我们通过extends关键字建立子类与父类的继承关系:格式:子类 extends 父类
-
继承相当于子类把父类的功能复制了一份,包括私有资源
注意:虽然私有资源继承了,但是私有资源不可用,原因是被private限制了访问,私有资源只能在本类使用
注意:构造方法不能继承,原因是:构造方法要求名字是本类的类名,我们不能在子类中出现父类名字的构造方法
- 继承是可以传递的:爷爷的功能会传给爸爸,爸爸的功能会传给孙子
注意:爸爸从爷爷那里继承的功能,也会一起传给孙子
-
Java的类是单继承的:一个子类只能有一个父类,但是一个父类可以有多个子类
-
子类在继承了父类以后,如果对父类的功能不满意
可以在不修改父类功能的【满足OCP原则】前提下,在子类中,重写继承过来的这个方法
重写需要满足的规则:两同 两小 一大,我们可以在重写的方法上加@Override注解验证是否写对
-
继承是一种is a的关系,强耦合,关联性特别强,而且类的继承机会只有一次,要谨慎使用
-
子类可以直接使用父类的所有非私有资源
练习题:
package cn.tedu.oop;
import java.util.Random;
import java.util.Scanner;
/本类用于复习面向对象的相关知识/
public class TestOOP {
public static void main(String[] args) {
//8.提示并接收用户传入的宠物昵称
System.out.println(“请您输入宠物的名字:”);
String name = new Scanner(System.in).nextLine();
//9.触发对应的构造函数,创建小猫类的对象
Cat c = new Cat(name);
//10.与宠物做互动
System.out.println(“按回车执行:”);
while(true){
new Scanner(System.in).nextLine();
int r = new Random().nextInt(6);
switch ®{
case 0:c.feed();break;
case 1:c.play();break;
default:c.punish();break;
}
}
}
}
//1.创建父类:宠物类,描述宠物这一类事物
class Pet{
//2.定义宠物类的属性
String name;//电子宠物的姓名
int full;//饱食度
int happy;//快乐度
//3.1 生成本类的全参构造
public Pet(String name, int full, int happy) {
this.name = name;
this.full = full;
this.happy = happy;
}
//3.2 创建本类的含参构造
public Pet(String name){
//只需要用户起宠物名即可,饱食度与快乐度的初始值都是50
//实际上底层会触发全参构造,名字是用户起的,其他两个是预先设置好的默认值
this(name,50,50);
}
//4.1定义宠物类的功能1–喂宠物吃东西
public void feed(){
//先判断宠物是不是吃饱了,如果吃饱了,结束整个喂食方法
if(full == 100){
System.out.println(name+“已经吃饱啦~”);
return;//遇到return关键字,整个方法直接结束
}
//如果没有吃饱,就给宠物喂食,一次增加10的饱食度
System.out.println(“给”+name+“喂食:”);
full = full + 10;
System.out.println(“饱食度:”+full);
}
//4.2定义宠物类的功能2–陪宠物玩
public void play(){
//先判断宠物还有没有饱食度,如果没有饱食度了,就不能玩了,结束整个玩的方法
if(full == 0){
System.out.println(name+“已经饿的玩不动了…”);
return;//遇到return关键字,整个方法直接结束
}
//如果饱食度不为0,就可以玩耍,每次玩耍快乐度+10,饱食度-10
System.out.println(“陪”+name+“玩耍”);
happy += 10;
full -= 10;
System.out.println(“快乐度:”+happy);
System.out.println(“饱食度:”+full);
}
//4.3定义宠物类的功能3–宠物的惩罚方法
public void punish(){
System.out.println(“打”+name+“的PP,哭叫声:”+cry());
happy -= 10;
System.out.println(“快乐度:”+happy);
}
//4.4定义一个哭的方法–宠物被打哭了
public String cry(){
return “此处有哭叫声”;//这个位置没有明确的叫声,因为子类会重写
}
}
//5.创建子类小猫类
class Cat extends Pet{
//6.由于父类的无参构造已经没有了,所以这里要手动调用父类的含参构造
public Cat(String name) {//养猫的时候要给猫起昵称
super(name);//表示调用父类的含参构造
}
//7.重写父类的cry();
@Override
public String cry(){
return “喵~”;
}
}
5.面向对象的三大特性:多态
- 前提:为了忽略子类型之间的差异,统一看作父类类型,写出更加通用的代码
比如:把Cat看作Animal,把Dog看作Animal,把Bird看作Animal,如果方法需要设置传入的参数,可以buy(Animal a)
比如:把算术异常、输入不匹配异常都看作是Exception,统一捕获处理,只写一个解决方案
-
概念:在同一时刻,同一个对象,代表的类型不同,拥有多种形态
-
多态的要求:继承 + 重写
-
多态的口诀1:父类引用指向子类对象:父类型的引用类型变量保存的是子类对象的地址值
-
多态的口诀2:编译看左边,运行看右边:
父类中定义的功能,子类才能使用,否则报错
多态中,方法的定义看的是父类的,方法的实现看的是子类重写后的功能
- 多态中资源的使用:
1)成员变量:使用的是父类的
2)成员方法:对于方法的定义看的都是父类的,对于方法实现,重写后使用的是子类的
3)静态资源:静态资源属于类资源,不存在重写的概念,在哪个类中定义的,就属于哪个类
- 向上造型与向下造型
1)这两种都属于多态,只不过是多态的两种不同的表现形式
2)向上造型【最常用】
可以把不同的子类型都看作是父类型,比如Parent p = new Child();
比如:花木兰替父从军,被看作是父类型,并且花木兰在从军的时候,不能使用自己的特有功能,比如化妆
3)向下造型
前提:必须得先向上造型,才能向下造型
子类的引用指向子类的对象,但是这个子类对象之前被看作是父类类型,所以需要强制类型转换
Parent p = new Child(); 然后:Child c = (Child) p;
比如:花木兰已经替她爸打完仗了,想回家织布,那么这个时候,一直被看作是父类型的花木兰必须经历“解甲归田”【强制类型转换】这个过程,才能重新被看作成子类类型,使用子类的特有功能
为什么有向下造型:之前被看作是父类类型的子类对象,想使用子类的特有功能,那就需要向下造型
6.构造方法
-
格式 :修饰符 类名当做方法名(){ } 注意:与类同名且没有返回值类型
-
构造方法作用:用于创建对象,每次new对象时,都会触发对应的构造函数,new几次,触发几次
-
一个类中默认存在无参构造,如果这个构造不被覆盖的话,我们可以不传参数,直接创建这个类的对象
-
如果这个类中提供了其他的构造函数,默认的无参构造会被覆盖,所以记得手动添加无参构
-
构造方法也存在重载的现象:无参构造 含参构造 全参构造【创建对象+给所有的属性赋值】
7.this与super
-
this代表的是本类,super代表的是父类
-
当本类的成员变量与局部变量同名时,我们可以通过this.变量名指定本类的成员变量
当父类的成员变量与子类的变量同名时,我们可以通过super.变量名指定父类的成员变量
- 我们可以在本类构造函数的第一行
使用this();调用本类的无参构造 / 使用this(参数); 调用本类对应参数的构造方法
构造函数的调用只有这一种方式,或者创建对象时被动触发,不能在外面自己主动调用
构造函数直接不能互相调用,否则会死循环
- 我们可以在子类构造函数的第一行
使用super();调用父类的无参构造 / 使用super(参数); 调用父类对应参数的构造方法
注意:子类默认调用super();父类的无参构造,如果父类没有无参构造,需要手动指定调用哪个含参构造
8.对象创建的过程
- 前提:对象是根据类的设定来创建的,目前我们可以在类中添加很多的元素:
属性 方法 静态方法 构造代码块 静态代码块 局部代码块 构造方法…所以不限制类里具体写什么,取决于业务
-
对象创建的过程:Phone p = new Phone();
-
需要在堆内存中开辟一块空间,用来存放对象
-
对象需要完成初始化,比如对应的属性都有自己的对应类型的默认值
-
对象创建完毕后,会生成一个唯一的地址值用于区分不同的对象
-
将这个地址值交给引用类型变量来保存
-
后续如果想要使用这个类的功能,可以从引用类型变量中保存的地址值找到对应的对象做进一步的操作
-
匿名对象:new Phone();
匿名对象是没有名字的对象,所以创建过程:
-
需要在堆内存中开辟一块空间,用来存放对象
-
对象需要完成初始化,比如对应的属性都有自己的对应类型的默认值
-
对象创建完毕后,会生成一个唯一的地址值用于区分不同的对象
那么我们使用匿名对象只能使用一次,并且一次只能使用一个功能
new Phone().video();//创建匿名对象1,调用看直播的方法
new Phone().message();//创建匿名对象2,调用看发短信的方法
9.代码块与它们的执行顺序
1.静态代码块 static { }
位置:类里方法外
执行时机:随着类的加载而加载,最先加载到内存,优先于对象进行加载,直到类小消失,它才会消失
作用:一般用来加载那些只需要加载一次并且第一时间就需要加载资源,称作:初始化
2.构造代码块 { }
位置:类里方法外
执行时机:创建对象时执行,创建几次,执行几次,并且优先于构造方法执行
作用:用于提取所有构造方法的共性功能
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
最后
笔者已经把面试题和答案整理成了面试专题文档
量中保存的地址值找到对应的对象做进一步的操作
- 匿名对象:new Phone();
匿名对象是没有名字的对象,所以创建过程:
-
需要在堆内存中开辟一块空间,用来存放对象
-
对象需要完成初始化,比如对应的属性都有自己的对应类型的默认值
-
对象创建完毕后,会生成一个唯一的地址值用于区分不同的对象
那么我们使用匿名对象只能使用一次,并且一次只能使用一个功能
new Phone().video();//创建匿名对象1,调用看直播的方法
new Phone().message();//创建匿名对象2,调用看发短信的方法
9.代码块与它们的执行顺序
1.静态代码块 static { }
位置:类里方法外
执行时机:随着类的加载而加载,最先加载到内存,优先于对象进行加载,直到类小消失,它才会消失
作用:一般用来加载那些只需要加载一次并且第一时间就需要加载资源,称作:初始化
2.构造代码块 { }
位置:类里方法外
执行时机:创建对象时执行,创建几次,执行几次,并且优先于构造方法执行
作用:用于提取所有构造方法的共性功能
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-a2Uqqm5G-1710959588973)]
[外链图片转存中…(img-FEgxivlJ-1710959588973)]
[外链图片转存中…(img-emOWLFHC-1710959588973)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-uHbPzw86-1710959588974)]
最后
笔者已经把面试题和答案整理成了面试专题文档
[外链图片转存中…(img-75zvUvZw-1710959588974)]
[外链图片转存中…(img-yQwi2FVJ-1710959588975)]
[外链图片转存中…(img-9p0IyPkW-1710959588975)]
[外链图片转存中…(img-qgiInLlA-1710959588975)]
[外链图片转存中…(img-XSpnSq9T-1710959588976)]
[外链图片转存中…(img-NFnb4bfL-1710959588976)]