那些年我们掉过的java的坑(五)
1.Throwable是所有异常的基类,包含两个子类: Error和Exception。Exception又分为被检查的异常(CheckedException),运行时异常(RuntimeException)。其实异常就是程序执行过程中发生没有实现预料到的情况。
- Error:表示程序运行时出现了严重的错误,不可恢复。
- Exception:需要使用try…catch…finally的异常。
- RuntimeException:Java编译器不会检查它。也就是说,当程序中可能出现这类异常时,倘若既"没有通过throws声明抛出它",也"没有用try-catch语句捕获它",还是会编译通过。例如,除数为零时产生的ArithmeticException异常,数组越界时产生的IndexOutOfBoundsException异常都属于运行时异常。一定要处理,否则发送了程序就会死再这。
- CheckedException:Exception类本身,以及Exception的子类中除了"运行时异常"之外的其它子类都属于被检查异常。Java编译器会检查它。此类异常,要么通过throws进行声明抛出,要么通过try-catch进行捕获处理,否则不能通过编译。例如,当通过clone()接口去克隆一个对象,而该对象对应的类没有实现Cloneable接口,就会抛出CloneNotSupportedException异常。一定要处理,否则程序就编译不过。
2.File类的常用方法
- File(String pathname)根据指定路径创建File对象,注意:\在字符串中需要"\\"表示
File file = new File("C:\\Trstary")
; - createNewFile()若存在返回false,否则创建文件或者文件夹
- delete()
- isFile()判断是否是文件
- isDirectory判断是否是文件夹
- listFiles()查询目录下面的所有File类型(文件或者文件夹)
- mkdir()创建目录
- exists()对于文件是否存在
3.Socket编程,通过字节流InputStream和OutputStream
服务型
public static void main(String[] args) throws IOException
{
//创建一个ServerSocket,用于监听客户端Socket连接请求
ServerSocket ss = new ServerSocket(8888);
System.out.println("server start");
//采用循环方式监听客户端的请求
while(true)
{
//侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。
Socket socket = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream ps = new PrintStream(socket.getOutputStream());
String s = br.readLine();
ps.println("收到:"+s);
ps.close();
br.close();
socket.close();
}
}
客户端
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost", 8888);
PrintStream ps = new PrintStream(socket.getOutputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
ps.println("你好");
//这个是非阻塞,所以需要轮询
while (true) {
String str = br.readLine();
if (null != str) {
System.out.println(str);
break;
}
}
ps.close();
br.close();
socket.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
4.java序列化和反序列化:Java序列化是指把Java对象保存为二进制字节码的过程,Java反序列化是指把二进制码重新转换成Java对象的过程
- 序列化的类需要实现Serializbale这个接口
- static代表的类成员,transient代表对象的临时数据,这两种成员不能够被序列化(代表这种类型的数据为默认值存入序列化中,反序列化出来也是默认值)
- 举个栗子就略了
- 序列化是针对对象,不是类
5.类加载的3个步骤,
- 装载,根据路径找到对应的class文件,引入
- 链接,链接又分为3步
- 检查,检查class文件正确性
- 准备,给类中的静态变量分配空间
- 解析,将符号引用改为直接引用
- 初始化,对静态变量和静态代码块执行初始化工作
6.符号引用和直接引用。在java中,一个java类将会编译成一个class文件。在编译时,java类并不知道引用类的实际内存地址,因此只能使用符号引用来代替。比如org.simple.People类引用org.simple.Tool类,在编译时People类并不知道Tool类的实际内存地址,因此只能使用符号org.simple.Tool(假设)来表示Tool类的地址。而在类装载器装载People类时,此时可以通过虚拟机获取Tool类 的实际内存地址,因此便可以既将符号org.simple.Tool替换为Tool类的实际内存地址,及直接引用地址。
7.GC(垃圾回收器)会对不可达对象进行内存回收,不要轻易调用System.gc(),性能会凉凉。
public static void main(String[] args) {
Integer a = new Integer(1);
Integer b = new Integer(2);
b=a; //这里的new Integer(1)就是“不可达”
}
8.Collection集合
- List:是有序的Collection集合,按照进入的顺序进行保存对象。子类有LinkedList(底层是采用链表实现,线程不同步)、ArrayList(底层是采用数组实现,线程不同步)、Vector(底层是采用数组实现,线程同步)
- Set:主要的特点是元素不能重复,所以需要提供好equals()方法。子类有HashSet(无序的元素)、TreeSet(按照配置的顺序排放元素的)
- Map:键值对,hash需要配好HashCode()。子类有HashMap(线程不同步,允许一个null键)、Hashtable(线程同步,不允许null键)、TreeMap(是有序的散列表,它是通过红黑树实现的。它一般用于单线程中存储有序的映射)等等
9.如何进HashMap变为线程安全
Map m = Collections.synchronizedMap(new HashMap());
10.Collection和Collections有声明区别
- Collection就是集合List和Set的父类
- Collections就针对集合的包装类,可以说是工具类