day02 数据类型,运算符
字符的存储
字符数据存的是ascii码中字符对应的数字的二进制
0: 48
A: 65
a: 97

二、八、十六进制(讲的很清晰)
八进制和十六进制的出现是为了便于观察和表示二进制:因为可以直接从八进制和十六进反推出二进制。
十进制虽然便于表示二进制,但是不便于推算出二进制


public static void main(String[] args) {
int a ;
a = 0b10;//二进制,十进制为2
System.out.println(a);
a = 010;//八进制,十进制为8
System.out.println(a);
a = 0x10;//十六进制,十进制为16
System.out.println(a);
a = 0xf;//十六进制,十进制为15
System.out.println(a);
}
Integer缓存
Integer i1 = 1;//自动装箱,相当于调用了Integer.valueOf()
Integer i2 = 1;
System.out.println(System.identityHashCode(i1));//3232
System.out.println(System.identityHashCode(i2));//3232
System.out.println(System.identityHashCode(new Integer(1)));//1234
Java 对于 -128** 到 **127 范围内的整数做了缓存
由于 1 在 [-128, 127] 的缓存范围内,i1 和 i2 实际指向的是 同一个缓存对象。
解释:
Integer i1 = 1;和Integer i2 = 1;
这两行用了 自动装箱(autoboxing) 语法,相当于:
Integer i1 = Integer.valueOf(1);
Integer i2 = Integer.valueOf(1);
由于 1 在 [-128, 127] 的缓存范围内,i1 和 i2 实际指向的是 同一个缓存对象。
所以:
System.identityHashCode(i1) == System.identityHashCode(i2) // true
new Integer(1)
这一行显式创建了一个新的对象,即使数值相同,也会是不同的堆对象:
注意:对象比较一律用equals()。用==比较对象时,比较的是变量里存的实际值(对象的地址)
Integer i1 = 444;
Integer i2 = 444;
System.out.println(i1==i2);//false
System.out.println(i1.equals(i2));//true
hashCode() 和 System.identityHashCode(Object x)
1. hashCode() 是可重写的
dog.hashCode()调用的是 对象的hashCode()方法,可以被类重写。- 如果你没有在
Dog类中重写hashCode(),它默认使用的是Object类的实现:
public native int hashCode(); // 在 Object 中
而这个默认实现,就是基于对象的内存地址生成的哈希值,和 System.identityHashCode() 的结果一样。
2. System.identityHashCode(Object x) 的作用
- 它总是返回对象内存地址生成的哈希值,不管
x.hashCode()有没有被重写。 - 所以即使你在类中重写了
hashCode(),System.identityHashCode()仍会给你对象的“内存地址生成的哈希”。
hashCode 和 equals 的规则(必须遵守)
- 一致性:同一个对象多次调用
hashCode()应返回相同值; - 如果
a.equals(b)返回 true,那么a.hashCode() == b.hashCode()必须为 true; - 如果
a.hashCode() == b.hashCode()不一定a.equals(b)
如果你重写的equals(), 你需要重写 hashCode() 是为了确保对象在基于哈希的数据结构(如 HashMap、HashSet)中能正确工作。
null 值
在 Java 中,null 表示一个引用变量不指向任何对象。
它只能赋值给引用类型变量(例如 String, Integer, Dog 等),表示它“什么也不指向”。
判断一个引用型变量是否为null直接用 if(obj == null){}
数据类型


在java代码中写的整数字面量默认是int类型,浮点数字面量默认是double类型

类型转换
赋值时的自动类型转换:小范围的类型可以直接赋值给大范围类型

表达式的自动类型转换:

!!!!在表达式中,byte、short、char 是直接转换成int类型再参与运算的!!!!
byte b1 =1;
byte b2 = 1;
int i = b1 + b2;
char c1 = 'a';
char c2 = 'a';
int i1 = c1 + c2;

强制类型转换:


整数相除
两个整数相除的结果还是整数
int a = 9;
int b = 2;
double i = a / b * 1.0;
System.out.println(i);//4.0
重点:整数除法先发生了!
a / b
a和b都是int类型,所以a / b执行的是 整数除法。9 / 2结果是 4,不是 4.5(Java 会直接丢弃小数部分)。
再乘以 1.0
4 * 1.0就是4.0(变成了double类型,但为时已晚)
正确方式:在需要保留小数时,务必提前把参与除法的变量转成 double 类型,否则默认用的是整型除法。
double i = 1.0 * a / b;
运算符

异或运算
你可以在一连串的异或操作中随意调整顺序和括号位置,这在算法设计(如加密、数据校验)中非常有价值。
public class XORLaws {
public static void main(String[] args) {
int a = 5; // 二进制: 0101
int b = 3; // 二进制: 0011
int c = 7; // 二进制: 0111
// 交换律: a ^ b == b ^ a
int xor1 = a ^ b;
int xor2 = b ^ a;
System.out.println("交换律:");
System.out.println("a ^ b = " + xor1);
System.out.println("b ^ a = " + xor2);
System.out.println("交换律成立: " + (xor1 == xor2));
// 结合律: (a ^ b) ^ c == a ^ (b ^ c)
int xor3 = (a ^ b) ^ c;
int xor4 = a ^ (b ^ c);
System.out.println("\n结合律:");
System.out.println("(a ^ b) ^ c = " + xor3);
System.out.println("a ^ (b ^ c) = " + xor4);
System.out.println("结合律成立: " + (xor3 == xor4));
}
}
“+” 符号可以做字符串连接符: 能算则算,不能算就在一起

Java 的字符串拼接(使用 +)具有自动调用对象的 toString() 方法的机制:
Student s1 = new Student();
Student s2 = new Student();
String sss = s1+" "+s2;

自增、自减运算符
只能操作变量,不能操作字面量
int a = 1;
a++;
2++;//错误写法
赋值运算符
扩展的赋值运算符隐含了强制类型转换

关系运算符

在 Java 中,比较运算符(>, <, >=, <=)只能用于以下几种情况:



如何比较其他对象?

逻辑运算符

位运算



运算符优先级
实际使用:括号搞定一切
注意一点:&&的优先级大于||
System.out.println(10 > 3 || 10 > 3 && 10 < 3); // true
//但是实际使用中,建议使用括号

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



