10.11
1.Java的三大特征:封装、继承、多态
封装:利用抽象数据类型将数据和基于数据的操作封装在一起,数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保留一些对外接口使之与外部发生联系。(抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。)
继承:一个类继承另一个类,则称继承的类为子类,被继承的类为父类。个性对共性的属性与方法的接受,并加入个性特有的属性与方法。继承后子类自动拥有了父类的属性和方法,但是父类的私有属性和构造方法并不能被继承。子类可以写自己特有的属性和方法,目的是实现功能的扩展,子类也可以复写父类的方法即方法的重写。
多态:多态是以封装和继承为基础的。多态是指允许不同子类型的对象对同一消息做出不同的响应,也就是同样的对象调用了同样的方法但是实现了不同的功能。
引用多态:父类的引用可以指向子类对象,也可以指向本类对象,但不能使用一个子类的引用指向一个父类的对象。
(eg:动物(父类)、狗(子类):可以 Animal a = new Animal(); Animal b = new Dog(); 但不能Dog a = new Animal();)
方法多态:创建本类对象时,调用的方法为本类方法;创建子类对象时,调用的方法为子类重写的方法或继承父类的方法。
2.访问修饰符public,private,protected,以及不写(默认)时的区别?
public(外部类):对所有用户开放,所有用户都可直接调用
private:私有。除了class自己之外,任何人都不可直接使用,私有财产神圣不可侵犯,即便是子女,朋友,都不可使用。
protected:对于子女、朋友来说,就是公开的,可自由使用,无任何限制;而对于其他的外部class,protected就变成private。(同一个包中的类,若不在同一个包中,必须为其子孙类才可使用)
默认:default(外部类):对于朋友和自己(同包)来说,就是公开的,子女也不可用。
修饰符 | 当前类 | 同包 | 子类 | 其他包 |
---|---|---|---|---|
public(外部类) | √ | √ | √ | √ |
private | √ | × | × | × |
protected | √ | √ | √ | × |
默认:default(外部类) | √ | √ | × | × |
10.12
1.java中最基本的数据类型
数据类型 | 字节型 | 短整型 | 整型 | 长整型 | 浮点型 | 双精度 | 字符型 | 布尔型 |
---|---|---|---|---|---|---|---|---|
数据类型 | byte | short | int | long | float | double | char | boolean |
所占内存 | 8 | 16 | 32 | 64 | 32 | 64 | 16 | / |
封装类 | Byte | Short | Integer | Long | Float | Double | Character | Boolean |
byte字节型1字节 8bit 最大存储数据量是255,存放的数据范围是-128~127之间
short短整型2字节 16bit最大数据存储量是65536,数据范围是-32768~32767之间
int整型4字节 32bit最大数据存储容量是2的32次方减1,数据范围是负的2的31次方到正的2的31次方减1
long长整型8字节 64bit最大数据存储容量是2的64次方减1,数据范围为负的2的63次方到正的2的63次方减1
float单精度4字节 32bit数据范围在3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F
double双精度8字节 64bit数据范围在4.9e-324~1.8e308,赋值时可以加d或D也可以不加
char字符型用单引号
boolean布尔型true/false(只有真假两种结果)
除了基本类型(primitive type)和枚举类型(enumeration type),剩下的都是引用类型(reference type)。
2.Java之String、StringBuffer、StringBuilder的区别分析
- String 类型和 StringBuffer 类型的主要性能区别在于:
String 是不可变的对象。因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后,JVM 的 GC 就会开始工作,影响性能,可以考虑使用可变字符序列StringBuilder - Java.lang.StringBuffer 线程安全的可变字符序列。类似于 String 的字符串缓冲区,但不能修改。可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
- 每个字符串缓冲区都有一定的容量。只要字符串缓冲区所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区数组。如果内部缓冲区溢出,则此容量自动增大。从 JDK 5.0 开始,为该类增添了一个单个线程使用的等价类,即 StringBuilder 。与该类相比,通常应该优先使用 StringBuilder 类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。但是如果将 StringBuilder 的实例用于多个线程是不安全的。需要这样的同步,则建议使用 StringBuffer 。
也就是在大部分情况下 StringBuilder > StringBuffer > String(操作次数越大,越稳定)。
10.13
1.float f=3.4;正确么?
不正确,因为3.4是双精度,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要 强制类型转换 float f =(float)3.4; 或者写成float f =3.4F;
数据类型转换必须满足如下规则:
- 不能对boolean类型进行类型转换。
- 不能把对象类型转换成不相关类的对象。
- 在把容量大的类型转换为容量小的类型时必须使用强制类型转换。
- 转换过程中可能导致溢出或损失精度,例如:
·····int i =128;
·····byte b = (byte)i;
因为byte类型时8位,最大值为127,所以当强制转换为int类型值128时候就会导致溢出。 - 浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入。
- 自动类型转换
必须满足转换前的数据类型的位数要低于转换后的数据类型,例如: short数据类型的位数为16位,就可以自动转换位数为32的int类型,同样float数据类型的位数为32,可以自动转换为64位的double类型。 - 强制类型转换
- 条件是转换的数据类型必须是兼容的。
- 格式:(type)value type是要强制类型转换后的数据类型。
- 隐含强制类型转换
- 整数的默认类型是 int。
- 浮点型不存在这种情况,因为在定义 float 类型时必须在数字后面跟上 F 或者 f。
2.short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?
对于short s1 = 1; s1 = s1 + 1;由于1是int类型,因此s1+1运算结果也是int 型,需要强制转换类型才能赋值给short型。short s1 = 1;s1= (short)s1 +1;
而short s1 = 1; s1 += 1;可以正确编译,因为s1+= 1;相当于s1 = (short)(s1 + 1);其中有隐含的强制类型转换。
10.14
多线程、并发及线程的基础问题(还要再看看,不理解的)
1. Java 中能创建 volatile 数组吗?
能,Java 中可以创建 volatile 类型数组,不过只是一个指向数组的引用,而不是整个数组。我的意思是,如果改变引用指向的数组,将会受到 volatile 的保护,但是如果多个线程同时改变数组的元素,volatile 标示符就不能起到之前的保护作用了。
2. volatile 能使得一个非原子操作变成原子操作吗?
一个典型的例子是在类中有一个 long 类型的成员变量。如果你知道该成员变量会被多个线程访问,如计数器、价格等,你最好是将其设置为 volatile。为什么?因为 Java 中读取 long 类型变量不是原子的,需要分成两步,如果一个线程正在修改该 long 变量的值,另一个线程可能只能看到该值的一半(前 32 位)。但是对一个 volatile 型的 long 或 double 变量的读写是原子。