N 个值得一看的后端代码片段

点赞再看,Java进阶一大半

三元运算符大家肯定有使用过,国外论坛有这么一个问题:Ternary operator: bad or good practice?三元运算符:坏习惯还是好习惯?

最高赞的回答是一个名为Ted Dziuba的老哥说的。

为了便于阅读,如果三元组适合一行 80 个字符,我才会使用它。

For the sake of readability, I only use a ternary if it fits into one 80-char line.

精彩文章推荐

大家好,我是南哥。

一个Java学习与进阶的领路人,相信对你通关面试、拿下Offer进入心心念念的公司有所帮助。

⭐⭐本文收录在《Java学习进阶指南》:github.com。。

1. 数据类型

1.1 static修饰的变量

本文所有内容在企业考核的笔试题出现频率很高,而且是易错题大家注意下

南友们在玩Java时有没发现,下面这样一个对象,我们即使没有给变量赋值,在创建它后这个变量依旧会有默认值

java 复制代码
class A {
    int a;
}

System.out.println(new A().a);
java 复制代码
程序执行结果:
0

有时前端同学要求后端给个默认值0,我们甚至不用动手,Java编译器就把活给干完。

这实际上是Java语言的一个特性,对于实例变量即成员变量,如果是基本数据类型都会有一个默认值。不同的基本类型默认值不同,我们看看以下各种基本类型的默认值。

java 复制代码
int a; //0
short b; //0
long c; //0
float d; //0.0
double e; //0.0
boolean f; //false
byte g; //0
char h; //空字符

1.2 自动类型提升

(1)Java中的byte、short、char进行数学计算时都会提升为int类型,很容易忽略的基础知识,南哥慢慢道来。

以下代码的运行正常吗?

java 复制代码
byte b1 = 1, b2 = 2, b3;
b3 = b1 + b2;

答案在你意料之中,就是编译报错。

shell 复制代码
# 报错内容
java: 不兼容的类型: 从int转换到byte可能会有损失

既然byte、short、char进行数学计算时都会提升为int类型,那我们就需要在运行过程中把结果转换成byte类型。正确的做法如下。

java 复制代码
b3 = (byte)(b1 + b2);

(2)但假如byte变量是这样的写法,我们给b1和b2都加个final,很神奇,编译不会报错。

java 复制代码
final byte b1 = 1, b2 = 2, b3;
b3 = b1 + b2;

这种情况是一个特殊情况,Java编译器会为其进行特殊处理,我们称它为编译时常量表达式的求值。b1、b2、b3都是常量值,b3在编译阶段就会被编译器进行赋值,不会涉及到上面我们提到的数学计算提升为int类型,也就不会编译错误。

(3)但如果是这种情况呢?

java 复制代码
final byte b1 = 1; byte b2 = 2, b3;
b3 = b1 + b2;

以上两个byte变量,只有一个final修饰,也就是说对b3赋值运算不能在编译时进行,那这段代码依旧会报错,我们还是需要把结果转换为byte类型。

正确做法如下。

java 复制代码
b3 = (byte)(b1 + b2);

1.3 byte溢出

byte类型的数据范围在-128 ~ 127,当这个值超过127会转变成 - 128。为什么呢?

java 复制代码
byte i = 127;
System.out.println(++i);
shell 复制代码
程序执行结果:
-128

byte类型的最大值127在二进制中表示为01111111,当我们对127的值增加1时,每位加1后都会产生进位,导致的结果就是所有的位都会翻转(从01111111变成10000000),而10000000十进制的表示就是-128。

1.4 Bollean赋值

业务开发编写最多就是条件语句了,特别在迭代年代比较旧的老项目,一套接一套的if语句。

既然见识了那么多条件语句,那以下代码的执行结果是什么?

java 复制代码
Boolean flag = false;
if (flag = true) {
    System.out.println("true");
}
else {
    System.out.println("false");
}

在Java里,条件判断是有赋值的功能,try语句同样也有。此时falg在条件判断里被赋值了。

shell 复制代码
程序执行结果:
true

2. 程序运算

2.1 类型提升

三元运算符的坑,相信不少南友遇到过。。。我们来看看三元运算符是什么?

Java中的三元运算符是一种简洁的条件表达式工具,其语法格式为:条件 ? 表达式1 : 表达式2。

如果条件为真(true),则表达式的结果是表达式1;如果为假(false),则结果是表达式2

假如是这种情况呢,南哥问:o1最终的数据类型是什么?

java 复制代码
Object o1 = true ? new Integer(1) : new Double(2.0);

上面的代码行其实等同于这一行。

java 复制代码
Object o1 = true ? new Double(1.0) : new Double(2.0);

三元运算符的一个非常关键的细节就是类型的统一化。Double类型的数据范围更大于Interger类型,所以Java编译器会对值类型进行类型提升,最终把Integer类型提升为Double类型。

2.2 自增问题

下面是南哥编写的两个i++自增的易错问题,面试考核经常出现在笔试题。

(1)南哥第一问:以下代码执行的结果是什么?

java 复制代码
int i = 0;
i = i++ + i; 
shell 复制代码
程序执行结果:
1

(2)南哥第二问:以下代码执行的结果是什么?

java 复制代码
int i = 0;
i = i++;
System.out.println(i);
shell 复制代码
程序执行结果:
0

2.3 String对象

我们创建一个String对象,JVM在背后实际上做了很多功夫,String对象在常量池、堆内存都有可能存在。我们具体问题来具体分析下。

(1)以下代码段不包含 引用类型,只是单纯的字面量拼接,所以只会创建一个对象存在于常量池中。

java 复制代码
String s = "JavaProGuide" + "南哥" + 666;

(2)以下代码段包含了引用类型,一共创建了3个对象,猜对了吗?

java 复制代码
String s = "Hello";
s = s + " world!"

"Hello"、" world!"都属于字面量,所以它们都会被加入到Java字符串常量池中。

s + " world!"这么一个代码段涉及了引用类型,所以它在内存里创建了一个新的String对象,并不存在于常量池,而是存在于堆内存里。

(3)以下代码段一共创建了2个对象,分别存在于常量池、堆内存。

java 复制代码
String str = new String("JavaProGuide");

首先new对象会把该String对象放到堆内存里,这是第一个。而过程中会先检查常量池是否存在JavaProGuide,如果常量池没有则会创建一个JavaProGuide的String对象放于常量池中。

戳这,《JavaProGuide》作为一份涵盖Java程序员所需掌握核心知识、面试重点的Java学习进阶指南。

欢迎关注南哥的公众号:Java进阶指南针。公众号里有南哥珍藏整理的大量优秀pdf书籍!

我是南哥,南就南在Get到你的有趣评论➕点赞➕关注。

创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️

相关推荐
爬菜几秒前
异常(5)
java
梦兮林夕11 分钟前
从零掌握 Gin 参数解析与验证
后端·go·gin
bobz96521 分钟前
IPSec IKE PSK 与扩展支持Xauth账户密码
后端
supermodule21 分钟前
基于flask的一个数据展示网页
后端·python·flask
苹果酱056724 分钟前
Golang的数据库备份与恢复
java·vue.js·spring boot·mysql·课程设计
315356691329 分钟前
manus邀请码申请手把手教程
前端·后端·面试
青石路43 分钟前
经由同个文件多次压缩的文件MD5都不一样问题排查,感慨AI的强大!
java·后端
木头没有瓜1 小时前
Mybatis集合嵌套查询,三级嵌套
java·tomcat·mybatis
知行021 小时前
23中设计模式之观察者模式
java·观察者模式·设计模式
RainbowSea1 小时前
5. MySQL 存储引擎(详解说明)
数据库·后端·mysql