OnJava01--面向对象基础 & 操作符
OnJava01-面向对象基础 & 操作符
1、对象无处不在
1.1、数据保存在哪
(1)寄存器
速度最快的数据存储方式,直接包存在CPU里。数量很有限,只能按需分配。Java中不能直接控制寄存器的分配。
(2)栈(Stack)
- 数据存储在随机存取存储器(RAM)里,处理器可以通过栈指针直接操作该数据。
- 效率仅次于寄存器。
- Java在创建程序时就要明确栈上所有对象的生命周期,约束了程序的灵活性,因此对象引用(但不仅是对象引用)会保存在栈上,而对象本身不在。
(3)堆(Heap)
- 通用的内存池,也存储在RAM空间
- 用于存放所有Java对象
- 堆的使用非常灵活,可以随时new对象,Java会在堆上为该对象分配内存空间
- 灵活的代价:分配和清理堆存储要比栈存储花费更多的时间--如今Java的堆内存分配机制已经非常高效,不需过度关注此问题
(4)常量存储
- 常量通常直接保存在程序代码中,因为值不会改变
(5)非RAM存储
未保存在应用程序中的数据。典型例子:
- 序列化对象:转换为字节流,并可以发送到其他机器的对象
- 持久化对象:磁盘上的对象,JDBC、Hibernate等
1.2 特殊情况:基本类型
对于基本类型,Java是直接创建一个“自动变量”,而不是引用,该变量会直接在栈上保存它的值。运行效率也较高。
1.3 无需销毁对象
(1)作用域
- C/C++、Java的作用域范围都是通过大括号{} 来定义的。
- Java中不允许在外围的作用域中“隐藏”变量:
1 |
|
(2)对象的作用域
Java对象在其作用域结束后可能会依然存在。
垃圾收集器会监视所有通过new创建的对象,及时发现不再引用的对象,并释放所占用的内存。
1.4 基本类型的默认值
- 当变量作为类的成员存在时,Java才会初始化为该变量对应的基本类型的默认值
- 默认值机制不会应用于局部变量
1 |
|
2、操作符
2.1 Java操作符
- 几乎所有操作符都只能操作基本类型,例外的是 = 、==、 != 也能操作对象
- String类型也支持 + 和 +=
2.2 赋值(=)
基本类型的赋值:将一个地方的内容复制到另一个地方,a = b就是b的内容复制给a,赋值后修改a并不会影响b
对象的赋值:真正操作的是对象的引用,将一个对象赋值给另一对象,实际是将引用复制到另一个地方;c = d就是将c、d都指向d的对象。
- 这种现象称作“别名”,需要注意,将对象作为参数传递给方法时,也会产生别名!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20class Letter {
char c;
}
public class PassObject {
static void f(Letter y) {
y.c = 'z';
}
public static void main(String[] args) {
Letter x = new Letter();
x.c = 'a';
System.out.println("1: x.c: " + x.c);
f(x); // f方法内修改了x.c的值,实际改变了f()之外的对象
System.out.println("2: x.c: " + x.c);
}
}
/* Output:
1: x.c: a
2: x.c: z
*/
2.3 算术操作符(+ - * / %)
- 整数的除法会舍弃小数位,非四舍五入
- 支持快捷运算符,即 +=、 -=、*=、/=、%=
2.4 自动递增、自动递减(++、--)
- 前缀式、后缀式:先执行运算再生成结果还是相反
- 是有副作用的操作符:会改变操作数
2.5 关系运算符(<、>、<=、>=、==、!=)
测试对象是否相等:
- == 和 != 比较的是对象的引用
- 对于Integer对象的 == 比较:
- Java中会通过享元模式来缓存 -128 ~ 127 内的对象,所以多次调用Integer.valueOf此范围内的整数,得到的是同一个对象
- new Integer() 生成的对象都是新创建的,无论什么范围
2.6 位操作符
用来操作整数基本数据类型中的单个二进制位(bit)。
- 按位与:&
- 按位或:|
- 按位异或: ^
- 按位非(一元操作符,只对一个操作数操作):~
布尔类型:
- 支持&、|、^,但不支持~(可能是为了避免与!混淆)
- 按位操作布尔值时,不会“短路”
2.7 移位操作符
只能用来处理基本类型中的整数类型。
- << :左移,低位补0
- >> :右移,符号扩展,符号为正,高位插入0,否则插入1
- >>>: 无符号的右移,零扩展
2.8 类型转换
(1)截尾和舍入
- 执行窄化转型(eg. float -> int)时,Java做的是截尾操作(29.7 -> int 是29,而不是四舍五入后的30)
- 舍入需要使用round()方法:
1 |
|
(2)提升
- 对小于int类型的基本数据类型(char byte short)执行算术运算或按位运算时,运算执行前就会将值自动提升为int,结果也是int类型。如果要把结果赋值回较小的类型,需要使用强制类型转换。
- 表达式里出现的最大的数据类型决定了表达式最终结果的数据类型(eg,int + long -> long)
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!