查漏补缺
1.异常
运行时异常
NollpointerException 空指针异常
ClassCastException 类类型转换异常
ArrayIndexOutOfBoundsException 数组索引越界异常
ArithmeticException 算术异常
IoException IO流异常
2.序列化和反序列化
对象流
Java中的序列化是指:把Java对象转换为字节序列的过程
对象 ------通过序列化------> 01010101
Java中的反序列化是指:把字节序列恢复成Java对象
010101 ------通过反序列化-------> 对象
3.++操作
public class Test {
public static void main(String[] args) {
add a1 = new add();
a1.test();
}
}
class add{//++操作
public void test() {
int a = 5;
System.out.println(a++);
System.out.println(++a);
}
}
对于++操作我的理解是它会在这条语句结束后,再进行+1操作;
4.包装类
public class Test {
public static void main(String[] args) {
int x = 127;
int y = 127;
Integer a = 127;
Integer b = 127;
System.out.println(x == y);
System.out.println(a == b);
}
}
这一段代码的运行结果是什么?
很多人回答的都是ture false
但是运行结果确是ture ture
其实这里有一个坑,Integer 本来是一个类,它们的引用进行==操作时,结果应该不会相同,但是我们看Integer的源码可以看到(在源码class IntegerCache中 ),Integer类中自带缓存,在-128~127范围内的数据直接从缓存中取(在源码valueOf(int i)中),所以进行比较的时候结果为ture。
当我们把a 和 b 的值改为超过127(或小于-128)时返回的比较结果为false。
我们也可以用 Integer a = new Integer(127)来避免比较为ture的结果
5.引用数据类型
引用数据类型有 1.类(class)2.数组(Array)3.接口(Action)4.枚举(enum)
7.线程锁的问题
问题:类A中有非静态方法x,类B中有非静态方法y,请问在x方法和y方法上直接使用synchronized关键字分别修饰这俩个方法,那么在多线程环境下,这个俩个方法x和y,是否可以实现线程同步的效果?
直接上源码
public class test1 {
public static void main(String[] args) {
Object o = new Object();
A a = new A(o);
B b = new B(o);
a.start();
b.start();
}
}
class A extends Thread {
public Object t;
public A(Object o) {
// TODO Auto-generated constructor stub
this.t = o;
}
public void x(Object o) {
synchronized (o) {
String name = Thread.currentThread().getName();
for (int i = 0; i < 10; i++) {
System.out.println(i + "\t" + name);
}
}
}
@Override
public void run() {
// TODO Auto-generated method stub
x(t);
}
}
class B extends Thread {
public Object t;
public B(Object o) {
// TODO Auto-generated constructor stub
this.t = o;
}
public void y(Object o) {
synchronized (o) {
String name = Thread.currentThread().getName();
for (int i = 0; i < 10; i++) {
System.out.println(i + "\t" + name);
}
}
}
@Override
public void run() {
// TODO Auto-generated method stub
y(t);
}
}
代码可能不是很符合题意,但是知识点相同。由于问题中对两个类中的方法分别进行加锁,所以两个个线程拿到的锁都不是同一把锁,因此不能达到线程同步,我们可以对创建一个锁对象,如上Object o,类A和类B传入同一个锁对象,对方法进行加锁,以此实现线程同步。
8.取反
比如对1进行取反操作,1的二进制为00001,进行取反为11110,转换为十进制为-14
错误原因:对符号位未进行取反
9.read()
int read(); 从输入流读取数据的下一个字节。
返回值为int
范围0
至255
。
到达流的末尾,返回值为-1
。
int read(byte[] buf); 从输入流读取一些字节数,并将它们存储到数组b中 。
返回值为读取的字节数
到达流的末尾,返回值为-1
。
int read(byte[] buf,int a,int b); 从输入流的a位置读取b个字节的数据到一个字节数组buf。
返回值为读取的字节数,最大为b。
到达流的末尾,返回值为-1
。
10.基本数据类型转换
基本数据类型进行转换:
隐式转换:由小转大,自动进行转换,不会发生精度丢失
显示转换(强制类型转换):由大转小,会发生精度缺失。
需要注意一个问题
public static void main(String[] args) {
short a = 1; // 第一行
a += 1; // 第二行
a = a + 1; // 第三行
}
就是a += 1;和 a = a + 1; 的问题,大部分时候我们都认为这两行代码等价,但是如果数据类型不同时a += 1;比 a = a + 1;多一个强制类型转换,也就是说,数据类型不同时 a +=1 ;等价于 a = (short)(a + 1);
11.Map集合
Map集合的特点:存储的内容为键值对,键不可重复,值可重复。当存在映射关系时,优先考虑Map。
Map集合中entrySet方法的返回值为键值对的集合。
12.抽象
抽象方法不能被final和static修饰,因为抽象方法需要被继承重写,且抽象方法中没有方法体,若由static修饰则可通过类名调用。
13.反射
15.重写
class A {
public A() {
System.out.println(getName());
}
public String getName() {
return "lisi";
}
}
public class Test extends A {
public Test() {
System.out.println(getName());
}
public String getName() {
return "wangwu";
}
public static void main(String[] args) {
new Test();
}
}
输出为wangwu wangwu
原因:父类方法被子类重写后,父类调用的也是子类重写后的方法。
16.数值交换
怎么能把变量a和变量b的值进行交换?(要求不使用第三个变量)
a = a ^ b;
b = a ^ b;
a = a ^ b;
a = a + b;
b = a - b;
a = a – b;
17.线程
18.list
19.网络