类型
# 6. 类型
# 八种基本数据类型的大小,以及他们的封装类
基本类型 | 大小(字节) | 默认值 | 封装类 |
---|---|---|---|
byte | 1 | (byte)0 | Byte |
short | 2 | (short)0 | Short |
int | 4 | 0 | Integer |
long | 8 | 0L | Long |
float | 4 | 0.0f | Float |
double | 8 | 0.0d | Double |
boolean | - | false | Boolean |
char | 2 | \u0000(null) | Characte |
注:
int是基本数据类型,Integer是int的封装类,是引用类型。int默认值是0,而Integer默认值是null,所以Integer能区分出0和null的情况。一旦java看到null,就知道这个引用还没有指向某个对象,再任何引用使用前,必须为其指定一个对象,否则会报错。
boolean类型单独占4个字节,以boolean数组的形式使用boolean占一个字节
boolean在底层实际会调用int,那么既然int占4个字节,boolean也自然占4个字节。即,boolean类型占4个字节。
boolean数组在底层会用到byte指令,那么既然byte占1个字节,boolean数组中的boolean也就占1个字节。即,boolean数组中的boolean占1个字节。
# 类型之间的关系
# 一. 实现
1. 指的是一个类实现接口(可以是多个)的功能
2. 实现是类与接口之间最常见的关系
# 二. 泛化
泛化表现为继承或实现关系,具体形式为类与类之间的继承关系,接口与接口之间的继承关系,类与接口的实现关系.就是说一个类(子类)继承另一个类(父类)的功能,并可以增加他自己的新功能的能力.
eg.
Cat is a Animal 凡是能够满足is a 的表示"继承"
Kitchener like a FoodMenu 凡是能够满足like a 关系的表示"实现"
# 三. 依赖
是类与类之间的连接,表示一个类依赖于另一个类的定义,其中一个类的变化将影响另外一个类,依赖关系是单向的.比如:类A使用到了类B,这种依赖具有偶然性,临时性,是非常脆弱的关系.但是类B的变化会影响到类A.
1. 类B以参数的形式传入类A的方法 2. 类B以局部变量的形式存在于类A的方法中 3. 类A调用类B的静态方法
# 四. 关联
类与类之间的联接,它使一个类知道另一个类的属性和方法.
例如:如果A依赖于B,则B体现为A的全局变量
关联关系有双向关联和单向关联,用单箭头表示单向关联,双箭头或者不使用箭头表示双向关联 双向关联:两个类都知道另一个类的公共属性和操作 单向关联: 只有一个类知道另外一个类的公共属性和操作
eg.
- I has a pen 凡是能满足 has a 的表示关联关系
# 五. 聚合
是关联关系的一种,是强的关联关系;聚合关系是整体和个体的关系.普通关联关系的两个类处于同一层次上,而聚合关系的两个类处于不同的层次,一个是整体,一个是部分,同时,是一种弱的"拥有"关系.此时整体与部分之间是可分离的,他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享;比如计算机与CPU,公司与员工的关系等;表现在代码层面,和关联关系是一致的,只能从语义级别来区分
# 六. 组合
是关联关系的一种,是比聚合强的关联关系.他要求普通的聚合关系中代表整体的对象负责代表部分的对象的生命周期 组合关系是一种强的“拥有”关系,体现了严格的部分和整体的关系,部分和整体的生命周期一致。他同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束;比如你和你的大脑,window窗口和frame,在窗口中创建一个frame时必须把它附加到窗口上,当窗口消失时frame也就消失了;表现在代码层面,和关联关系是一致的,只能从语义级别来区分
# 几种关系所表现的强弱程度依次为:组合>聚合>关联>依赖
# Java自动装箱与拆箱
装箱
就是自动将基本数据类型转换为包装器类型(int-->Integer);调用方法:Integer 的 valueOf(int) 方法
拆箱
就是自动将包装器类型转换为基本数据类型(Integer-->int)。调用方法:Integer 的 intValue 方法
在Java SE5之前,如果要生成一个数值为10的Integer对象,必须这样进行:
Integer i = new Integer(10);
从Java SE5开始就提供了自动装箱的特性,如果要生成一个数值为10的Integer对象,只需要这样就可以了:
Integer i = 10;
面试题1: 以下代码会输出什么?
public class Main {
public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1==i2);
System.out.println(i3==i4);
}
}
2
3
4
5
6
7
8
9
10
运行结果:
true
false
2
为什么会出现这样的结果?输出结果表明i1和i2指向的是同一个对象,而i3和i4指向的是不同的对象。此时只需一看源码便知究竟,下面这段代码是Integer的valueOf方法的具体实现:
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
2
3
4
5
6
其中IntegerCache类的实现为:
private static class IntegerCache {
static final int high;
static final Integer cache[];
static {
final int low = -128;
// high value may be configured by property
int h = 127;
if (integerCacheHighPropValue != null) {
// Use Long.decode here to avoid invoking methods that
// require Integer's autoboxing cache to be initialized
int i = Long.decode(integerCacheHighPropValue).intValue();
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - -low);
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for (int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
从这2段代码可以看出,在通过 valueOf 方法创建 Integer 对象的时候,如果数值在 [-128,127] 之间,便返回指向 IntegerCache.cache 中已经存在的对象的引用;否则创建一个新的 Integer 对象。上面的代码中 i1 和 i2 的数值为100,因此会直接从 cache 中取已经存在的对象,所以 i1 和 i2 指向的是同一个对象,而 i3 和 i4 则是分别指向不同的对象。
面试题2: 以下代码会输出什么?
public class Main {
public static void main(String[] args) {
Double i1 = 100.0;
Double i2 = 100.0;
Double i3 = 200.0;
Double i4 = 200.0;
System.out.println(i1==i2);
System.out.println(i3==i4);
}
}
2
3
4
5
6
7
8
9
10
运行结果:
false
false
2
原因: 在某个范围内的整型数值的个数是有限的,而浮点数却不是。