Java|Java 基础知识

1.基本类型字节个数

类型 大小
byte 1个字节
char 2个字节
short 2个字节
int 4个字节
long 8个字节
float 4个字节
double 8个字节
boolean类型的长度依赖虚拟机实现不同而不同
在Oracle JVM规范中,boolean 是由int实现的,故是4个字节;boolean 数组 是由byte数组实现的,故有1个字节。
2.基本类型的值范围
类型 范围
byte -128 ~ 127
char 0 ~ 65535
short -32768 ~ 32767
int -2147483648 ~ 2147483647
long -9223372036854775808 ~ 9223372036854775807
float类型包括-∞,negative,-0,+0,positive,+∞,NaN
The NaN value is used to represent the result of certain invalid operations such as dividing zero by zero。(NaN表示无效操作)
NaN不能比较
float nan = Float.NaN; System.out.println(nan); System.out.println("NaN is equal NaN :"+(Float.NaN == Float.NaN)); System.out.println("0 is bigger NaN :"+(0 > Float.NaN)); System.out.println("0 is smaller NaN :"+(0 < Float.NaN)); System.out.println("0 is equal NaN :"+(0 == Float.NaN));

运行结果:
NaN NaN is equal NaN :false 0 is bigger NaN :false 0 is smaller NaN :false 0 is equal NaN :false

3.位操作
操作 符号
按位与 &
按位或
位非 ~
按位异或(xor) ^
按位同或(xnor) ==,!^ 例如:a==b,!(a^b)
左移 <<
逻辑右移(有符号右移) >>
算法右移(无符号右移) >>>
移位操作要注意的问题是高(低)位是补0还是补1和对char, byte, short型的操作:
(1)<< : (left-shift), 最低位补0
(2)>> : (signed right-shift), 右移过程使用符号位扩展(sign extension),即如果符号为为1则高位补1, 是0则补0,也就是逻辑右移
(3)>>> : (unsigned right-shit),右移过程使用零扩展(zero extension),即最高位一律补0,也就是算术右移
(4)移位操作的数据类型可以是byte, char, short, int, long型,但是对byte, char, short进行操作时会先把它们变成一个int型,最后得到一个int型的结果,对long型操作时得到一个long型结果,不可以对boolean型进行操作。
(5)移位操作符可以和=合并起来,即 <<= 、 >>= 和 >>>=。例如 a >>= 2; 表示将a右移两位后的值重新赋给a。当时在使用这三个操作符对 byte, char, short型数据进行操作时要注意
4.运算符优先级
优先级 运算符 结合性
1 () [] . 从左到右
2 ! +(正) -(负) ~ ++ -- 从右向左
3 * / % 从左向右
4 +(加) -(减) 从左向右
5 << >> >>> 从左向右
6 < <= > >= instanceof 从左向右
7 == != 从左向右
8 &(按位与) 从左向右
9 ^ 从左向右
10 从左向右
11 && 从左向右
12 从左向右
13 ?: 从右向左
14 = += -= *= /= %= &= = ^= ~= <<= >>= >>>= 从右向左
优先级不对,会出现如下错误:
error: bad operand types for binary operator '&'
错误代码: if(index & r != 0)
正确代码: if((index & r) != 0)
加括号就可以简单解决优先级的问题
5. Object类公有的方法:
  • equals
  • hashCode
  • toString
  • clone
  • finalize
6. == ,equals(), hashCode()
  • == 比较的是内存地址
  • equals() 比较的是内容
  • hashCode是一个int型的哈希值
结论
  • == 相等两个对象,equals() 也相等,hashCode()也相等 --(内存地址相同的两个对象)
  • == 不相等的两个对象,若equals() 相等,hashCode()也相等 --(内存地址不同的对象,内容相等)
  • == 不相等的两个对象,若equals() 不相等,hashCode()可能相等,也能不相等 --(不同内存地址下的对象,内容不相等,哈希冲突则hash值相等,否则不相等)
原理
  • Object.equals() 比较的是内存地址
  • Object.hashCode() 依赖于Java虚拟机具体实现,一种实现是hashCode是内存地址
对于常用String类
  • String.equals()重写了Object.equals()方法,比较了每一个char
  • String.hashCode() 重写了Object.hashCode()方法,根据每个char的ascii码值计算得出一个hash值
对于自己定义的类
  • 需要重写Object.equals()方法,实现内容相等的判断逻辑(要遵守:自反性、对称性、传递性、一致性)
  • 同时需要重写Object.hashCode()方法,可用JDK7的工具类Objects.hash(object ...)获得hash值
  • 如果不同时重写Object.equals()和Object.hashCode(),禁止使用自定义类的equals方法。切记!切记!
  • HashMap 使用对象做key 的时候,必须重写对象的equals(),同时必须重写对象的hashCode(),因为HashMap首先比较HashCode,然后在调用equals
测试代码
import java.util.Objects; public class HashCode {public static void main(String []args){ Person p1 = new Person("张三",20); Person p2 = new Person("张三",20); Person p3 = new Person("李四",21); //String 已经覆盖了Object类的equals 以及 hashCode //String p1 = "张三"; //String p2 = new String("张三"); //String p3 = "李四"; System.out.println("p1.equals(p2) :"+p1.equals(p2)); System.out.println("p1.hasCode:"+p1.hashCode()); System.out.println("p2.hasCode:"+p2.hashCode()); System.out.println("p3.hasCode:"+p3.hashCode()); }} class Person{String name; int age; public Person(String name,int age){ this.name = name; this.age = age; }//JDK7 (java.util.Objects.hash(...)) @Override public int hashCode(){//自定义hashCode //final int prime = 31; //int result =1; //result = prime*result+age; //result = prime*result+name.hashCode(); // //return result; //JDK7 工具类hashCode //根据 JDK7内部实现,如果hash的参数需要保证有正确的hashCode,否则可能会出错 //原因 调用了参数本身的hashCode方法return Objects.hash(this.name,this.age); }//仿照String 的equals的方法 @Override public boolean equals(Object obj){ if(this == obj) return true; if(obj instanceof Person){ Person other = (Person) obj; if(this.age == other.age && this.name.equals(other.name)) return true; } return false; } }

输出结果
p1.equals(p2) :true p1.hasCode:24022540 p2.hasCode:24022540 p3.hasCode:26104873

参考链接:
Chapter 2. The Structure of the Java Virtual Machin
Java 8 种数据类型 字节大小,int 4个字节,boolean几个字节
java的移位操作详解,左移和右移
Java的位运算符详解实例——与(&)、非(~)、或(|)、异或(^)
bad operand types for binary operator “&” java
【Java|Java 基础知识】Object.hashCode implementation
深入java 的equals方法和hashCode方法
HashCode() 和 equals()的若干问题
Best implementation for hashCode method
HashCode和equals()

    推荐阅读