曦曦xixi

曦曦xixi

暂无个人简介
佛山市
Java后端
2023
广州软件学院
Java后端

该用户为会员

会员专享项目教程/ 答疑等服务

Day 6 ✅ 今天做了:继续复习 1.包机制 定义:其实就是一个文件夹,分类存放.class类文件,避免类名冲突,方便管理。 导包:import java.util.ArrayList;->在一个类里使用其他包的类 作用:①区分同名类:项目里可以有多个 User 类,只要包不同就不冲突; ②类的分类管理:按功能 / 模块分包(controller、service、dao、utils); ③控制访问权限:配合访问修饰符实现封装; ④企业级规范:所有项目必须分包,不允许所有类放默认包。 ———————————————————————————————— 2.访问修饰符 定义:给变量 / 方法 / 类装门禁 权限范围:①private-只能在本类访问②默认不写-同包下所有类可访问 ③protected-不同包的子类也可访问④public-公开类,导入包就能访问 ———————————————————————————————— 3.封装-面向对象三大特征的基础 定义:成员变量私有化,对外提供公共的get/set方法,方法内部可以加校验、逻辑、保护 作用:只暴露使用部分,内部实现隐藏,数据安全 —————————————————————————— 4.继承-面向对象三大特征的前提 定义:子类自动拥有父类非私有属性和方法 语法:子类 extends 父类 作用:大量复用代码 规则:只支持单继承,可以多层继承,无法继承父类私有化内容,可以重写父类方法 **super关键字** 定义:调用父类变量、方法、构造器 语法:super.变量/方法()/() —————————————————————— 5.多态--面向对象三大特征的最终目标 定义:对于同一行为,不同对象的表现不同 作用:①将静态方法调用到不同实现版本上 ②数据类型转换 ③动态生成接口 ④方法调用 ⑤状态转移 实现多态的前提:必须有继承关系、方法重写、父类引用指向子类 格式:父类 引用名 = new 子类(); 动态绑定机制:编译时看父类,运行时看子类 上下转型,上转为父类引用指向子类,自动;下转把子类的父类引用转回子类以启动子类私有内容,手动强制。 —————————————————————————————————————————————— 📚 今日总结:包机制、访问修饰符、封装、继承、多态

Day 5 ✅ 今天做了:继续复习 1.面向过程vs面向对象 ①面向过程定义: 以“过程/步骤”为核心,将程序视为一系列按顺序执行的操作步骤,数据与操作分离(先定义数据,再写操作函数) ②面向过程的缺陷: 1.数据与操作分离 → 导致代码混乱、易错(如数组分散存储学生信息) 2.业务逻辑分散 → 修改需求需大改多处代码 3.扩展困难 → 添加新功能需重写大量代码 ③面向对象定义: 以“对象”为核心,将程序视为相互协作的对象集合,数据与操作封装在对象中(把现实世界的事物抽象为对象,对象包含属性和行为) ④面向对象优点: 1.可维护:数据与行为绑定 2.易拓展:通过继承等方式拓展(下面会讲) 3.映射关系清晰:数据与数据之间关联清晰,不需要特地辨识(如人为辨别张三的name和socre) 4.更符合人脑思维的对象之间的交互来解决问题而不是流程解决问题 4.团队协作低效 → 依赖全局数据结构,易冲突) ———————————————————————— 2.类和对象的定义 ①类是对象的模板,定义了对象的属性和行为,类由员变量员方法组成 ②对象是按照类创建的具体示例,根据同一个类可以创建多个对象 —————————————————————————— 3.成员变量: 定义:即对象的属性/特征 语法:修饰符 数据类型 变量名; 访问:对象名.属性名 变量作用域:java按定义只有两种作用域:1.局部变量2.成员变量 ①就近原则:局部变量和成员变量重名时,优先使 ②this 区分:this.变量名 → 强制访问成员变量 —————————————————————————— 4.对象创建流程(举例Dog dog = new Dog()) ①1.声明引用 Dog dog; 操作:在栈内存中,开辟一个小空间,创建局部变量 dog; 初始值:null(空引用,代表还没有指向任何对象); 此时:堆中没有任何对象,只有栈里的一个空引用 ②2.创建对象 new Dog() 1.类加载 检查 Dog 类是否已加载到方法区: 未加载 → 读取 Dog.class 文件,将类的结构(成员变量、构造方法、普通方法)存入方法区; 已加载 → 直接复用方法区的类信息。 2.分配堆内存 在堆内存中开辟一块连续空间,创建 Dog 对象实例: 给对象的成员变量分配空间,执行默认初始化(比如 int=0,String=null); 执行 Dog() 构造方法,完成显式初始化; 3.生成内存地址 给堆中的这个对象分配一个唯一的十六进制地址(比如 0x112233) ③3.赋值引用 dog = 堆对象地址 —————————————————————————— 5.成员方法:定义、方法调用、方法重载、方法递归调用 ①定义:即对象的行为或功能 语法:修饰符 返回值类型 方法名(参数列表) { 方法体; return 返回值; // 无返回值写void } 注意:1.调用带参方法,要对应参数列表传入可兼容数值 2.一个方法只能有一个返回值,类型可以是任意 ②方法调用 格式:对象名.方法名(参数可选) 内存分析: 每次方法调用,jvm都会创建一个独立的栈帧空间(方法执行最小的数据单元) 栈帧:局部变量表+操作数栈+动态链接+方法返回地址 调用步骤: 1.程序启动:JVM 加载MethodDemo类,找到入口main()方法 2.main 栈帧入栈:JVM 为main方法创建栈帧,压入虚拟机栈(栈底),开始执行 main 方法 3.暂停 main,准备调用 add:执行到demo.add(10,20),main 方法暂停执行 4.创建 add 栈帧:JVM 为add方法创建新栈帧 5.参数传递(值传递):把实参10、20复制到 add 栈帧的局部变量表 6.add 栈帧入栈:成为栈顶,JVM 开始执行 add 方法的代码 7.add 方法执行完毕:计算结果30,准备返回 8.返回值传递:把30交给 main 栈帧的局部变量result 9.add 栈帧出栈:add 方法执行结束,栈帧销毁,内存释放 10.恢复 main 执行:回到 main 方法的暂停处,继续执行打印代码 11.main 栈帧出栈:main 方法结束,线程终止 不同的方法调用:1.静态方法调用2.实例方法调用3.构造调用 调用返回:正常返回,栈帧出栈;异常返回,异常上抛 ③方法重载 定义:在同一个类中,允许定义多个方法名相同,但参数列表不同的方法 规则:1.参数个数不同;2.参数类型不同;3.参数顺序不同(类型不同时有效) 底层原理:编译器根据方法名 + 参数列表唯一识别方法,调用时自动匹配对应参数的方法 **可变参数** 定义:允许方法接收0 个、1 个或多个 ** 同类型的参数; 规则:1.一个方法最多只能有 1 个可变参数 2.可变参数必须放在参数列表的最后一位 3.调用时可传:0 个值、1 个值、多个值、直接传数组 语法:语法: 访问修饰符 返回类型 方法名(数据类型... 形参名) { } 本质:可变参数在方法内部,就是一个数组 ④方法递归调用 定义:自己调用自己 满足递归前提条件:1.必须有调用停止的条件(无法停止导致栈帧溢出)2.每次调用都必须向递归头靠近(问题规模不断缩小) 经典问题:1.递归求阶乘 n! 2.递归求斐波那契数列 —————————————————————————— 6.构造器 定义:特殊的构造方法-创建对象的专用方法,new关键字创建对象时自动调用,用于初始化成员变量 规则:1.方法名 必须和类名完全一致(大小写敏感)2.没有返回值,不能写 void;3.一个类可以有多个构造器(重载) ———————————————————————————————————————————— 7.this关键字 定义:调用当前对象自己 用途:1.this.成员变量:区分成员变量和局部变量重名 2.this.成员方法:调用本类的其他成员方法 3.this():调用本类的其他构造器(必须写在构造器第一行) —————————————————————————————— 📚 今日总结:面向过程vs面向对象、类和对象的定义、成员变量、对象创建流程、成员方法、构造器、this关键字

Day 4 ✅ 今天做了:继续复习 1.数组赋值机制(基本数据类型vs引用数据类型) 举例:int a = 10;int b = a; VS int[] arr1 = {1, 2, 3};int[] arr2 = arr1; 基本数据类型:值传递,拷贝的是数值,两个变量相互独立,修改一个不影响另一个 引用数据类型(数组):引用传递,拷贝的是地址,两个变量指向同一个数组,修改一个影响另一个 ———————————————————————————————————— 2.数组进阶操作:拷贝、反转、扩容、排序、查找 ①拷贝 数组拷贝的核心就是创建新数组,再拷贝原数组元素 方式:for循环拷贝、Arrays.copyOf( )、System.arraycopy( )、数组克隆(clone ( )) 注意:如果数组元素都是基本数据类型那么就是深拷贝,如果有引用数据,这些拷贝就只能获取到元素引用地址(浅拷贝)。 System.arraycopy是native方法(底层 C/C++ 实现),批量拷贝时效率最高;Arrays.copyOf`底层也是调用`System.arraycopy,只是封装后更易用。 **深拷贝与浅拷贝** 区别在于:深拷贝只获取被拷贝对象数值,额外创建内存空间储存,浅拷贝是获取引用地址,共享储存资源。 解决:重写对象的Object或者使用对象序列化 ②反转(核心思路是首尾元素交换,循环到数组中间(避免重复交换)) 1.利用索引int start = 0;和int end = 数组名.length-1 2.创建临时变量来交换变量值 3.如果是数组全部翻转,则需要写进while(start<end)循环,利用start++和end--来逐个反转 ③扩容(原则上,数组一旦完成初始化,他的长度是固定不变的) 但是可以新建一个全新的数组重新初始化,过程:先扩大长度再把原数组的元素值全部复制,然后让原数组的变量名重新指向新的数组,之前内存中的旧数组因为没有了变量指向所以会被jvm垃圾回收。 ④排序(无规律元素按规律排序) 冒泡排序: 核心思想:设置循环的次数限制条件 1.访问两个连续的元素,比较大小,依照大的在后原则交换元素值 2.假设一个数组长度为n第一次访问是0,1索引,第二次访问1,2……一直到第n-1次访问到n-2,n-1索引的元素,此时数组最大的元 素已经在最后一个位置 3.外层循环的次数限制实际为n长度的数组理论最高的遍历数组次数-因为每一次遍历都把当前数组的最大值放在最后一位 4.内层循环的次数限制实际为每轮遍历中可比较元素的位置限制,即已经排好序的最大元素位置不访问,这个比较次数应该是 逐轮减少的 Arrays排序:Arrays工具类的方法,这个方法更底层,效率更高 1.默认升序,Arrays.sort(arr1); 2.指定范围排序,Arrays.sort(arr2, 1, 4);// 范围是左闭右开,排序索引1、2、3的元素 3.字符串数组排序,按字典顺序排 String[] arr3 = {"banana", "apple", "orange"}; Arrays.sort(arr3); ⑤元素查找(算法内容再究) 查找方法大致有:线性、二分、跳跃、哈希查表(不同业务场景不同选择导致不同的查找效率) ———————————————————————————— 3.二维数组 二维数组是数组的数组,本质是 “行 + 列” 的表格结构,支持规则 / 不规则(锯齿)数组; 声明和初始化:int[][] arr = new int[][]{{数组1},{数组2},{数组3}} 内存分配:变量名存储第一层数组的地址,第一层数组内部存储第二层数组的地址 经典案例:打印九九乘法表(二维数组版本)、找二维数组的最大值 📚 今日总结:数组赋值机制、数组进阶操作、二维数组

Day 3 ✅ 今天做了:继续复习 1.数组的定义 什么是数组:是存储 “同一类型数据” 的容器 数组四大核心特点: 储存的元素类型一致、初始化后数组固定不变、元素在内存中的储存是连续的且可以通过索引访问、数组属于引用数据类型 ———————————————————————————— 2.数组的基本使用:声明+初始化、数组的访问与遍历、数组的工具类 ①声明+初始化:即先分配内存空间再赋值 数组声明:数据类型[ ] 数组名; 初始化:静态初始化,提前知道该数组所存储的所有元素,元素长度由元素个数决定: 数据类型[ ] 数组名 = new 数据类型[ ]{元素1, 元素2, ...}; 动态初始化:不清楚具体元素,但规定了数组的长度: 数据类型[ ] 数组名 = new 数据类型[长度]; ②数组的访问和遍历: 访问数组,通过数组索引访问,数组的索引从0 开始,最大索引是数组长度-1:数组名[索引]; 数组的遍历,即对数组的所有元素逐一访问,普遍使用两种方式: for循环(索引自增+1访问)→public class ArrayForLoop { public static void main(String[] args) { int[] scores = {90, 85, 95, 80, 100}; int sum = 0; // 普通for循环:i是索引,从0到length-1 for (int i = 0; i < scores.length; i++) { sum += scores[i]; // 累加每个元素 System.out.println("第" + (i+1) + "个学生成绩:" + scores[i]); } System.out.println("成绩总和:" + sum); // 输出450 } } for-each循环(只能获取元素,但不需要索引)→ for (数据类型 变量名 : 数组名) { // 变量名代表当前遍历到的元素 } 数组的声明初始化和访问遍历需要注意几点: 索引越界,即使用超过数组长度-1的索引访问数组 空指针异常,数组变量未能指向有效数组 声明和初始化格式建议使用最规范的那种,简化写法容易混淆出错 数组一旦初始化就要确定长度,无论是静态还是动态初始化,初始化后无法进行动态增删 ———————————————————————————————————————— 3.数组的内存分析 以int[ ] scores = new int[ ]{90,85,95}为例 分位两部分来看,第一个部分是int[ ] scores ,其中int声明为数组储存的元素类型,这里指的是整型数组 scores指的是数组变量。数组变量存储着该数组的首地址,因为数组元素地址连续的特性,后续数组其他元素的访问都是用过首地址+索引来完成的。故解释了,为什么int[ ] scores数组不是基本数据类型而是引用数据类型,因为数组变量本身就是只存放了一个数组的内存首地址罢了。此时使用的是栈内存。 第二部分new int[ ]{90,85,95},实例化通知jvm分配三个连续的、能存放int数据的内存空间(堆内存),并且把90,85,95塞进对应的内存空间。 最后 = ,完成赋值,即数组变量获取到该数组首地址:scores → 0x123 → [90, 85, 95](地址0x123) 📚 今日感悟:数组定义、数组的基本使用、数组的内存分析

Day 2(补4.21) ✅ 今天做了:继续复习 1.二/十进制换算 1bit储存一个0或1,1byte=8bit 十进制转二进制:除2取余直到结果为0,余数倒序排列,向前补0 二进制转十进制:按位加权求和,顺序从右往左,第一个位权是2⁰ —————————————————————————————————— 2.底层运算原反补码 补码设计目的:二进制原码运算涉及正负符号位,需要消除符号位影响,整数的底层存储都是补码形式 规则:正数相同,负数取反再+1 个人简易不完全正确理解:举例5+(-5) 1字节可以存放256个不同整数(含正负),看成为由128个坐标组成的可循环周期(一个○),mod=2^8=256。 正数的补码与原码相同,补码为00000101,从0-127即128个不同整数,此时为正数周期 负数的补码,需要进入到负数周期,先从00000101走完正数周期的坐标点,即5→127(加法), 再反方向走到对应位置,即-128→-5(减法变加法),刚好走完256坐标点一个mod,即00000101+(11111111+1); 11111111(2)=255(10)<256,所以需要补1来表示一个完整周期,结果为11111011,5+(-5),两个坐标点重合,与00000101+11111011=00000000结果吻合。故,负数的补码过程就诞生了,原码变反码,即为+11111111,反码+1变补码,即为增加缺少的mod的溢出量1. ———————————————————————————————————————————————————————— 3.运算符 运算符=算术运算符+赋值运算符+比较运算符+逻辑运算符+位运算符+三元运算符 ①算术运算符:加减乘除→+、-、*、/ ; 取余→%;自增/减→a++(--)或++(--)a **浮点数取余运算** 举例-10.5 % 3 = -1.5,a=-10.5,b=3,r=-1.5,a = b × n + r→r=a-(b × n ) 底层运算公式:a = b × n + r→r=a-(b × n ) 其中,n=a - (b × floor(a/b)),floor为向下取整,a/b = -10.5/3 = -3.5,向下取整为-4 所以,r = -10.5 - (3 × -4) = -10.5 + 12 = 1.5,遵循“浮点数取模余数符号和被除数一致”原则,输出为-1.5 注意点: 1.由于浮点数底层存储为近似值,故浮点数取余有可能会丢失精度,如0.1 % 0.03 ≠ 0.01 2.高精度场景使用BigDecimal.remainder() 3.任何取模运算(整数 / 浮点数)前,都要校验除数非 0,避免程序崩溃 **a++与++a的区别** a++:先取值后运算→a = 2;b = a++;→a=2;b=2;→a=3;b=2; ++a:先运算后取值→a = 2;b = ++a;→a=3;→a=3;b=3; ②赋值运算符→=、+=、-=、*=、/=、%= 以+=举例,其他一样。byte a = 10,计算a+=5; a+=b等同a = (a的数据类型)(a+b) **a+=b与a=a+b的区别** byte a = 10;a = a + 5; 报错:不兼容的类型(b+5自动转int,不能直接赋值给byte) 更改:a = (byte)(a + 5);手动强制转换 自动强制转换:a+=5;通过,输出15 原理:使用+=时jvm会自动对运算结果自动强制转换为a的数据类型 易错:first.+=与=+,前者是复合运算,后者是使用=赋值了一个(+a)的数据 sec.重点:使用+=自动强制转换导致的数据溢出且该错误jvm不会报错 修正:添加赋值范围校验 (long)num + 1 <= Byte.MAX_VALUE third.错误地循环使用+=拼接字符串,String 是 “不可变对象”,s += i本质是s = new String(s + i),循环次数越多,性能越差 修正:循环拼接字符串用StringBuilder ③比较运算符: 想等于==、不等于!=、大于>、小于<、大于等于>=、小于等于<=、是否类对象 instanceof ④逻辑运算符: a&b→当 a 和 b 同时为 true ,则结果为 true, 否则为 false;a&&b→当 a 和 b 同时为 true ,则结果为 true, 否则为 false a|b→当 a 和 b ,有一个为 true ,则结果为 true,否则为 false;a||b→当 a 和 b ,有一个为 true ,则结果为 true,否则为 false !a→取反,非,false>true,true>false;a^b→亦或,两者相同则为true,两者不同则为false ⑤位运算符:二进制运算 &→有 0 则 0,全 1 则 1→判断奇偶(&1) | →有 1 则 1,全 0 则 0→权限控制 ^→相同为 0,不同为 1→交换两个数(不用临时变量) ~→补码取反,结果需转原码→底层数值转换 <<→等价于 ×2ⁿ(无溢出时)→快速乘 2 >>→等价于 ÷2ⁿ(保留符号)→快速除 2 >>>→全部位右移 n 位,左边补 0,结果始终为正数→无符号数值处理 ⑥三元运算符 (条件)?结果1:结果2 注意:条件必须是boolean,结果1/2必须类型兼容 ⑦运算符优先级 口诀:括号第一,乘除加减;比较在后,逻辑跟;三元赋值,最后算;记不住就加括号 —————————————————————————————————————————————— 4.输入输出 输入→// 步骤1:创建Scanner对象(关联控制台输入流System.in) Scanner scanner = new Scanner(System.in); // 场景1:读取整数 System.out.print("请输入你的年龄:"); int age = scanner.nextInt(); System.out.println("你的年龄是:" + age); // 步骤2:关闭Scanner(释放系统资源) scanner.close(); 输出→System.out.print();打印不换行 →System.out.println();打印后自动换行 →System.out.printf();格式化输出 // 格式说明符:%d(整数)、%f(浮点数)、%s(字符串)、%.2f(保留2位小数) String name = "小明"; int age = 18; double score = 95.5; System.out.printf("姓名:%s,年龄:%d,成绩:%.2f\n", name, age, score); —————————————————————————————————————————— 5.控制结构 概念:默认程序是从上到下依次执行代码,控制结构就是控制代码执行顺序的语句 控制结构=顺序控制+分支控制+循环控制+跳转控制 ①分支控制:单分支if、双分支if-else、多分支if-else if(多个)-else,switch分支,嵌套分支 switch分支语句: switch (表达式) { case 常量值1: // 表达式等于常量值1时执行 break; // 跳出switch(可选,不写会穿透) case 常量值2: // 表达式等于常量值2时执行 break; default: // 表达式不等于任何常量值时执行(可选) break; } 易错:漏写break导致的case穿透 ②循环控制: for循环--打印9*9乘法口诀表 while循环--猜数字 do-while循环--密码验证 for-each循环--集合遍历 多重循环 ③跳转控制 break--跳出当前循环--break+outer标签实现跳出到指定循环 continue--跳出本次循环 return--跳出整个方法 —————————————————————— 📚 今日总结:二/十进制换算、底层运算原反补码、运算符、输入输出、控制结构

Day 1 ✅ 今天做了: 1.回顾cmd基本的dos命令:dir/cd/md/rd/del/ren/java/javac/java/cls/echo —————————————————————— 2.java注释://单行注释、/*多行注释*/ 文档注释:/**@return long 注册成功返回用户唯一ID,注册失败返回-1*/ ①类接口,标注核心功能业务场景设计目标 ②方法,标注核心功能参数含义约束规则返回值说明异常抛出说明 javadoc -d doc UserService.java 生成文档 —————————————————————————— 3.java程序最小单元:变量 = 数据类型+变量名+变量值 数据类型:约束数据种类,分配内存大小 变量名:映射内存实际物理地址的代号 变量值:存储在里面的具体数据 ———————————————————————————— 4.数据类型→基本数据类型+引用数据类型 ①基本数据类型:整型byte(1)/short(2)/int(4)/long(8);整型赋值常量默认为int,long类赋值需要声明L 浮点型:float(4)/double(8);浮点赋值常量默认double,float赋值需要声明F 字符型:char(2):单个英文字母占1,单个汉字占2 布尔型:boolean(1):true or false 包装类:基本数据类型的实例化工具 ②引用数据类型:类、接口、数组…… ———————————————————————— 5.浮点数比较常见误区:2.7==8.1/3(?) 结论:因为十进制转换二进制问题,小数转为二进制的无限循环小数后被有限的物理空间截断为近似值 2.7实际存储数值为2.70000000000000018...;8.1/3实际存储数值为2.6999999999999997... float和double对于小数的存储是近似存储,不能用于要求精度的场景,两小数比较相加等 解决方案:创建BigDecimal对象,传入字符串形式小数,再进行处理。 —————————————————————————— 6.数据类型转换:自动转换/强制转换/String转基本数据类型 6.1自动转换,条件:小转大(小杯的水倒入大水杯)byte<short<char<int<long<float<double ①赋值时的自动转换:int score = 95; double newScore = score; ②运算时的自动转换(坑点):byte、short、char的混合运算会先全部转成int再运算,最后结果只能用int接收 ③传参时的自动转换:类似①,满足方法参数是大范围,传入值是小范围 易发生问题的自动转换: ①int转float/long转double时,可能会丢失精度 虽然float范围比int大,但float的有效位数只有 6~7 位,当int数值超过有效位数时,会丢失精度 int bigInt = 2147483647; // int的最大值 float f = bigInt; System.out.println(f); // 输出2.14748365E9(和原int值2147483647不一致,精度损失) 同理,long的大数值转double也可能丢失精度。 ②byte/short不能自动转char(符号问题) byte/short是有符号类型(范围包含负数),char是无符号类型(范围 0~65535),所以不能自动转换: byte b = 97; // char c = b; // 报错!byte是有符号,不能自动转无符号的char char c = (char)b; // 必须强制转换,此时c='a'(正确) ③布尔类型不参与自动类型转换 6.2强制转换,大转小(大杯的水倒入小杯),不安全有可能数据溢出导致精度损失,需要手动设置显式声明 格式:(目标数据类型) 待转换的变量/数值;double num = 5.5; int numInt = (int) num; 强制转换的几个雷区: ①数值溢出: 例如:Java 整数采用 “补码” 存储,int是 32 位,最大值 + 1 后二进制位全部翻转,最高位(符号位)变成 1,结果变成int最小值(循环溢出)。 安全方案:转换前先判断范围,避免溢出 ②浮点→整型的强制转换只会直接丢弃小数部分,不会做任何四舍五入处理。 安全方案:先用Math.round()实现四舍五入,再强制转换 ③char 与 byte/short 的符号问题 char是无符号类型(0~65535),byte是有符号类型(-128~127),强制转换时保留二进制位,超出范围后符号位变为 1,结果成负数 安全方案:获取真实Unicode值再判断是否超出强转的类型范围 ④byte/short 运算后强制转换的顺序问题 byte a = 10; byte b = 20; byte c = (byte) a + b; // 报错:不兼容的类型 byte/short运算时会先自动转int,(byte) a只是把 a 转成 byte,但 b 还是会转 int,最终结果是 int,无法直接赋值给 byte。 解决方案:byte c = (byte) (a + b); ⑤浮点数强制转换,本身浮点存储就是近似存储,强制转换只会进一步放大精度损失 安全方案:用BigDecimal避免精度丢失,绝对不能用浮点强制转换 6.3基本数据类型与 String 的相互转换 基本数据类型→String:①空字符串 + " " ②String.valueOf() 推荐使用②,可以避免空指针问题 String→基本数据类型 使用其对应包装类的parseXxx()方法(返回基本类型),或valueOf()方法(返回包装类,推荐使用,可兼容 null) 注意事项: ①优先用String.valueOf()转 String:语义清晰,避免拼接空字符串的 “魔法操作”,团队协作更易理解; ②转换数值类型必加异常处理:用try-catch捕获NumberFormatException,并设置兜底值,避免程序崩溃; ③转换前先校验空值 / 格式:先判断String是否为 null / 空,再转换,减少异常触发; ④boolean 转换适配业务场景:不要依赖Boolean.parseBoolean()的默认规则,根据业务(比如 1 = 真 / 0 = 假)自定义判断; ⑤包装类 vs 基本类型:常用包装类(Integer/Double)接收转换结果,方便处理 null 值(比如数据库字段为 null 的场景)。 —————————————————————————————————————————————————————— 7.变量名称:标识符、关键字、保留字 7.1标识符:程序员给变量起的名称 需要按照命名规则,遵守命名规范 命名规则:1.由26字母,0-9,_或$组成 2.不能数字开头 3.不能使用关键字和保留字 4.严格区分大小写 5.不能有空格 命名规范:1.包名全小写 2.类、接口首字母大写 3.变量、方法名首字母小写(驼峰命名法) 4.常量全大写 7.2关键字:在java中有特定用途的标识符,全小写 7.3保留字:在当前版本未作为关键字使用但后续版本有可能变成关键字 📚 今日总结:dos命令、java注释、java变量三要素、数据类型、数据类型转换、变量名称

新人报道: 为什么来导航:科班毕业三年没有从事专业岗位(之前干现场运维的),现在想捡回来顺便学点新技术找个工作。然后逛来逛去选择鱼皮这里的社区。 目标:现在没有细致目标只有大体方向,太细致只会导致变化过多。先跟着java后端路线大概来一遍,然后专门花时间学AI方向的新东西。 本帖是新人打招呼帖子,后面学习情况会有专门记录,算是给自己点正向反馈。😋

下载 APP