JAVA面试题-CORE JAVA部分
1. 在main(String[] args)方法内是否可以调用一个非静态方法?
答案:不能
2. 同一个文件里是否可以有两个public类?
答案:不能
3. 方法名是否可以与构造器的名字相同? 答案:可以。
public class Test
{
public Test(String iceboy)
{
System.out.println(iceboy);
}
public void Test(String iceboy)
{
System.out.println(iceboy);
}
public static void main(String[] args)
{
Test a = new Test("abc");//输出“abc”
a.Test("iceboy");//输出“iceboy”
}
}
4. 初始化了一个没有run()方法的线程类,是否会出错?
答案:不会。
第一种方法:直接继承Thread类。
public class Test
{
public static void main(String[] args)
{
ThreadClass t = new ThreadClass();
t.start();
System.out.println("end");//输出“end”
}
}
class ThreadClass extends Thread //Thread类已经实现了空的run()方法。
{
}
第二种方法:实现Runnable接口
public class Test
{
public static void main(String[] args)
{
ThreadClass t = new ThreadClass();
Thread thread = new Thread(t);
thread.start();
System.out.println("end");
}
}
class ThreadClass implements Runnable
{
public void run() //必须有此方法否则编译报错。它是Runnable接口中的抽象方法。
{
System.out.println("Threads");
}
}
4. 局部内部类是否可以访问非final变量?
答案:不能访问局部的,可以访问成员变量(全局的)。
class Out
{
private String name = "out.name";
void print()
{
final String work = "out.local.work";//若不是final的则不能被Animal 使用.
int age=10;
class Animal
//定义一个局部内部类.只能在print()方法中使用.
//局部类中不能使用外部的非final的局部变量.全局的可以.
{
public void eat()
{
System.out.println(work);//ok
//age=20;error not final
System.out.println(name);//ok.
}
}
Animal local = new Animal();
local.eat();
}
}
5. 选择语句case中,允许使用的值有哪些? 答案:int,short,char,byte(都在int范围之内,且是整数)
6. Math,String是不可继承的。(final类)
Instanceof 后面跟的应该是OBJECT。
构造器可以是私有的。(private)
=与==意义是完全不同的。一个是赋值,一个是等于。
全局变量可以不进行初始化,如果使用一个局部变量,则这个局部变量要被初始化。
7. 在try-catch-finally块中的退出语句。
public class Test
{
public static void main(String[] args)
{
int a=1;
try
{
a=a/0;
}catch(Exception e)
{
System.out.println("catch");
return;//当return时,finally中的语句会执行。
//System.exit(0);//若用上这句,finally中的语句不会执行。直接返回,退出程序。
}
finally //当没有System.exit(0);时,无论是否发生异常它都会执行。
{
System.out.println("finally");
}
}
}
注: try-catch-finally块的顺序不能调换。
8. 下面都是正确的main方法签名。
public static void main(String[] args)
public static final void main(String[] args)
static public void main(String[] args)
static public synchronized void main(String[] args)
static public abstract void main(String[] args)//错误
9. if(-0.0 == 0.0)是相等还是不等?
答案:相等。
10.一个抽象类是否可以没有抽象方法?
答案:可以。
11.RandomAccessFile 类继承Object,并且实现了DataInput和DataOutput接口。
答案:正确
12.Collection与Collections的区别?
答案:Collection是一个接口,但 Collections却是一个辅助类,里面有很多静态的工具方法。而且很有用的。如:reverse
(List
list)
;sort(List
list, Comparator
c)
等。
Collections没有实现任何接口。它直接继承了Object。
13.class Child extends Parents{}
class Parents{}
是否可以这样声明类,在一个文件中?
答案:可以。无所谓的。
14.数组,无论是当前的,还是类等级的,都会被初始化。
String 是被初始化为 null,不是空字符。
null,““,”“,都是不同的。
“continue”只能在一个循环里(如for,do,while),它不能在case语句中出现。
Primitive(int,char,long等)数组是不能互相赋值的,即使它们本身可以。
一个Constructor可以抛出任何异常。
初始化块是按照声明的顺序执行的。
所有关于 NaN(Not a Number) 和 non-NaN 的比较,都返回false. 这条很重要。
==会产生编译错误,如果两边类型不匹配的话。
equals() 返回 false 如果对象类型不同,但不产生编译错误。
15.Java成员变量默认初始化的值。
成员变量类型 取值
byte-0 short-0 int-0 long-0L
char-'\u0000' float-0.0F double-0.0D boolean-false
所有引用类型 null
16. integer和long 操作 /和% 的话,可能会抛出ArithmeticException,比如除0。但是 float与double不会,即使是除以0。
double a=0;a=a/0;则a等于NaN。
17.普通内部类不可以拥有静态变量,但静态内部类可以。
File类没有任何处理文件内容的方法。InputStream 和 OutputStream 是抽象类, DataInput 和 DataOutput是接口。DataInputStream实现了DataInput接口。
18.面向对象的特征有哪些方面?
答案:
最基本特征:封装,继承,多态。
其他特征:抽象关联,聚合,组合,内聚,耦合
19.String是最基本的数据类型吗? String 和StringBuffer的区别?
答案:
String不是一最基本的数据类型。STRING的长度是不可变的,
STRINGBUFFER的长度是可变的。如果你对字符串中的内容经常进行操作,特别是内容要修改时,那么使用StringBuffer,如果最后需要String,那么使用StringBuffer的toString()方法
20.int 和 Integer 有什么区别
答案:int是基本类型。Integer是引用类型。Integer可以把String转换成int。
21.运行时异常与一般异常有何异同?
答案:
异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。
java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。
22.说出一些常用的类,包,接口,请各举5个?
答案:常用类-System,ArrayList,FileInputStream,Thread,Socket.
常用的包-java.io,java.util,java.sql,java.javax.naming,java.net
常用接口-Collection,Connection, Cloneable, Comparable, Serializable
23.说出ArrayList,Vector, LinkedList的存储性能和特性.
答案:ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。
24.设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。
注:因为这4个线程共享J,所以线程类要写到内部类中。
加线程:每次对j加一。
减线程:每次对j减一。
public class TestThreads
{
private int j=1;
//加线程
private class Inc implements Runnable
{
public void run()
{
for(int i = 0;i < 10;i++)
{
inc();
}
}
}
//减线程
private class Dec implements Runnable
{
public void run()
{
for(int i = 0;i < 10;i++)
{
dec();
}
}
}
//加1
private synchronized void inc()
{
j++;
System.out.println(Thread.currentThread().getName()+"-inc:"+j);
}
//减1
private synchronized void dec()
{
j--;
System.out.println(Thread.currentThread().getName()+"-dec:"+j);
}
//测试程序
public static void main(String[] args)
{
TestThreads test = new TestThreads();
//创建两个线程类
Thread thread = null;
Inc inc = test.new Inc();
Dec dec = test.new Dec();
//启动4个线程
for(int i = 0;i < 2;i++)
{
thread = new Thread(inc);
thread.start();
thread = new Thread(dec);
thread.start();
}
}
}
25.数组转换问题。
Object[] object = new Person[2];
Person [] person = new Person [3];
person = (Person [])object;//可以转换
int[] i = new int[2];
long[] l = new int[3];
i = (long[])l;//不可以转换
26.用socket通讯写出客户端和服务器端的通讯,要求客户发送数据后能够回显相同的数据。
Server.java:源代码
import java.net.*;
import java.io.*;
class Server
{
public Server()
{
BufferedReader br = null;
PrintWriter pw = null;
try
{
ServerSocket server = new ServerSocket(8888);//建立服务器端
Socket socket = server.accept();//监听客户端
//得到该连接的输入流
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//得到该连接的输出流
pw = new PrintWriter(socket.getOutputStream(),true);
//先读后写
String data = br.readLine();
System.out.println(data);//输出到控制台
pw.println(data);//转发给客户端
}catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
//关闭读写流
br.close();
pw.close();
}catch(Exception e)
{}
}
}
public static void main(String[] args)
{
Server server = new Server();
}
}
Client.java:源代码
import java.net.*;
import java.io.*;
class Client
{
public Client()
{
BufferedReader br = null;
PrintWriter pw = null;
try
{
Socket socket = new Socket("localhost",8888);//与服务器建立连接,服务器要先启
//得到Socket的输入与输出流
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
pw = new PrintWriter(socket.getOutputStream(),true);
//先写后读
pw.println("Client:你好!");
String data = null;
while(true)
{
data = br.readLine();
if(data!=null) break;
}
System.out.println(data);
}catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
br.close();
pw.close();
}catch(Exception e)
{}
}
}
public static void main(String[] args)
{
Client c = new Client();
}
}
27.谈谈final, finally, finalize的区别。
答案:
final 用于声明属性,方法和类,分别表示属性不可变,注意:如果是基本类型说明变量本身不能改变,如果是引用类型,说明它不能指向其他的对象了。但对象还是可以改变的。方法不可覆盖,类不可继承。
finally是异常处理语句结构的一部分,表示无论是否出现异常总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。
28.Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?
答案:可以继承其他类或完成其他接口,在swing编程中常用此方式。
29.Static Nested Class 和 Inner Class的不同,说得越多越好(面试题有的很笼统)。
答案:Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化。
30.&和&&的区别。
答案:&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and).另外,&也可以用于逻辑运算,与&&的区别在于&是非短路运算符,&&是短路运算符
31.HashMap和Hashtable的区别。
答案:HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都实现了Map接口, 主要区别在于HashMap允许空(null)键值(key)与空值(value),由于非线程安全,效率上可 能高于Hashtable,Hashtable不允许有空(null)键值(key)与空值(value)。
32.什么时候用assert?
答案:1.4新增关键字(语法),用于测试boolean表达式状态,可用于调试程序。使用方法 assert <boolean表达式>,表示如果表达式为真(true),则下面的语句执行,否则抛 出AssertionError。
33.GC是什么? 为什么要有GC?
答案:GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显式操作方法。
34.String s = new String("xyz");创建了几个String Object?
答案:两个,一个是对象,一个是对象的引用。
35.Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
答案:Math.round(11.5)==12
Math.round(-11.5)==-11,总是返回接近0的数。
36.short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
答案:
short s1 = 1; s1 = s1 + 1; 有错(s1+1运算结果是int型,需要强制转换类型)
short s1 = 1; s1 += 1;(没有错,s1==2)
37.sleep() 和 wait() 有什么区别?
答案:
sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间(休息),把执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复,时间到了会继续运行。调用sleep不会释放对象锁。
wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
38.Java有没有goto语句?
答案:没有
39.数组有没有length()这个方法? String有没有length()这个方法?
答案:
数组没有length()这个方法,有length的属性。
String有length()这个方法。
40.数组是不是基本类型?
答案:不是。
41.Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?
答案:
方法的重写Overriding和重载Overloading是Java多态性的不同表现。
重载Overload是一个类中多态性的一种表现,方法名必需相同,参数列表必需不同.(长度不同或类型不同),与返回值类型没有关系. 构造器也可以重载.方法名和参数列表都相同,只有返回类型不相同则是方法重复定义.编译出错. Overloaded的方法是可以改变返回值的类型。
重写Override是父类与子类之间多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。
42.Set里的元素能重复吗?那么用什么方法区分是否重复?
答案:Set里的元素是不能重复的,如果重复就重复的就不加到里面。用iterator()方法来区分
重复与否。应该覆盖equals()判断两个Set是否相等。
43.”==”与equal有何区别?
答案:“==”比较的是内存地址,equal比较的是内容本身。
44.给我一个你最常见到的runtime exception。
答案:IndexOutOfBoundsException 数组越界
NullPointerException 空指针异常
SystemException 系统异常
45.error和exception有什么区别?
答案:
Error表示系统级的错误和程序不必处理的异常,我们无法处理它。
Exception表示是可以捕捉或者需要程序进行处理的异常。
46.List, Set, Map是否继承自Collection接口?
答案:List,Set是。Map不是
47.abstract class和interface有什么区别?
答案:一个只能继承一个抽象类,但却可以实现多个接口。抽象类中可以有也可以没有抽象方法。并且可以定义和常规类一样的变量和方法。而接口中所有的方法都是抽象的,所
有的变量都是静态不可修改的。
48.abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?
答案:都不能。
49.接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类答(concrete class)?
答案:接口可以继承接口。接口间继承(extends),不能实现(implements)。
抽象类可以实现(implements)接口,但接口不能实现抽象类。抽象类间也用继承(extends)。
抽象类是否可继承实体类,但前提是实体类必须有无参的构造函数。
50.启动一个线程是用run()还是start()?有什么区别?
答案:启动一个线程是调用start()方法,这并不意味着线程就会立即运行,只是进入了可运行状态。直接调用run()方法不会产生线程,而是把它当作普通的方法调用,马上执行。
51.Constructor是否可被override?
答案:不可以,但可以重载。
52. Class.forName的作用?
答:调用该访问返回一个类名为指定字符串的类的对象。
53.文件读写的基本类有哪些?
答案:FileInputStream,FileOutputStread,File,IOException等。
54.写一个冒泡排序的程序。
public class Sort
{
public static void main(String[] args)
{
int[] array = {2,3,4,1,43,432,1,344,234,2,3,43,32,434,3432,43,2432,432,4,43};
int num = 0;
/*
冒泡排续
*/
for(int i = 0;i < array.length;i++)
{
/*
每下底一个元素,则调换的次数减一。
注意:j<array.length-i-1,不减一则数组下标越界。
*/
for(int j = 0;j<array.length-i-1;j++)
{
int temp = 0;
/*
两两比较若前面的大于后面的则进行调换。
*/
if(array[j] > array[j+1])
{
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
/*
输出排序后的数组
*/
System.out.println("****************已排序的数组********");
for(int i = 0;i < array.length;i++)
{
System.out.print(array[i]+" ");
num++;
if(num == 5)//每行输出5个。
{
System.out.println();
num = 0;
}
}
}
}
55.串行化的注意事项以及如何实现串行化?(Serializable)
答案:*******************************
56.线程的基本概念、线程的基本状态以及状态之间的关系
答案:*******************************
57.线程的同步、如何实现线程的同步?
答案:*******************************
58.几种常用的数据结构及内部实现原理。
答案:*******************************
59.Socket通信(TCP、UDP区别及Java实现方式)
答案:*******************************
60.Java的事件委托机制和垃圾回收机制
答案:*******************************
61.作用域public,private,protected,以及不写时的区别。
答案:private-类可见,不写-包可见
protected-包可见,并子类可见 public-都可见
62.Java的国际化
答案:*******************************
63.怎样让程序到后台去运行?
答案:*******************************
64.怎么把一个文件中的东西做全文替换。
答案:*******************************
65.ArrayList和Vector的区别?
答案:就ArrayList与Vector主要从二方面来说.
同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同步的
数据增长:当需要增长时,Vector默认增长为原来一倍,而ArrayList却是原来的一半。
66.char型变量中能不能存贮一个中文汉字?为什么?
答:是能够定义成为一个中文的,因为java中以unicode编码,一个char占16个字节,所以放一个中文是没问题的。
67.多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么?
答:
多线程有两种实现方法,分别是继承Thread类与实现Runnable接口
同步的实现方面有两种,分别是synchronized,wait与notify
68.垃圾回收机制,如何优化程序?
答案:*******************************
69.float型float f=3.4是否正确?
答:不正确。类型不匹配,应该用强制类型转换,如下所示:float f=3.4f;
70. Java中异常处理机制,事件机制?
答案:*******************************
71.现在输入n个数字,以逗号,分开; 然后可选择升或者降序排序;
import java.util.StringTokenizer;
import java.util.Arrays;
public class Test
{
public static void main(String[] args)
{
String s = "2,654,24,6554,3234,3544,666,354,5435,11";
StringTokenizer tok = new StringTokenizer(s,",");
//返回有多少个被分割元素
int count = tok.countTokens();
int[] result = new int[count];
//把分割得到的数字存到数组中去。
for(int i = 0;i<count;i++)
{
String temp = (String)tok.nextElement();
result[i] = Integer.parseInt(temp);
}
//排序
Arrays.sort(result);
for(int i = 0;i<result.length;i++)
{
if(i==0)
{
System.out.print(result[i]);
continue;//第一个元素的前面不打印“,”
}
System.out.print(","+result[i]);
}
System.out.println();//输出:2,11,24,354,654,666,3234,3544,5435,6554
}
}
72.金额转换,阿拉伯数字的金额转换成中国传统的形式如:
(¥1011)->(一千零一拾一元整)输出。
答案:************************************
73.当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
答案:能,一个对象的synchronized方法只能由一个线程访问。但其他线程可以同时访问这个对象的非synchronized方法
74.try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
答案:会执行,在return前执行。
75.编程题: 用最有效率的方法算出2乘以8等於几? 有C背景的程序员特别喜欢问这种问题。
答案:2 << 3 。如果是2的10次方则是:1<<10.
76.两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
答案:两个对象的值是否相同,根据的是equals方法,而hash code是由hashCode()方法决定。因此值相同的对象hash code可能不同。
77.当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
答案:是值传递。Java 编程语言只由值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用
是永远不会改变的。
。编程题: 写一个Singleton出来。
方式一:醉汉式
public class Singleton
{
private static Singleton test = new Singleton();//静态的。保留自身的引用。
//必须是私有的构造函数
private Singleton(){}
public static Singleton getInstance()//公共的静态的方法。
{
return test;
}
}
方式二:懒汉式
public class Singleton
{
private static Singleton test = null;//静态的。保留自身的引用。
//必须是私有的构造函数
private Singleton(){}
public static Singleton getInstance()//公共的静态的方法。
{
if(test == null)
{
test = new Singleton();
}
return test;
}
}
79.描述一下JVM加载class文件的原理机制?
答案:***********************
80.试举例说明一个典型的垃圾回收算法?
答案:***********************
81.请写一个java程序实现线程连接池功能?
答案:***********************
82.给定一个C语言函数,要求实现在java类中进行调用。
答案:***********************
83.编一段代码,实现在控制台输入一组数字后,排序后在控制台输出。
答案:***********************
84.列出某文件夹下的所有文件;
答案:***********************
85.实现从文件中一次读出一个字符的操作;
答案:***********************
86.列出一些控制流程的方法;
答案:***********************
87.多线程有哪些状态?
答案:***********************
88.编写了一个服务器端的程序实现在客户端输入字符然后在控制台上显示,直到输入"END"为止,让你写出客户端的程序。
答案:***********************
99.请用java写二叉树算法,实现添加数据形成二叉树功能,并以先序的方式打印出来.
答案:****************************************
100.调用系统命令实现删除文件的操作;
答案:****************************************
101.C++或Java中的异常处理机制的简单原理和应用。
答案:
当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常。违反语义规则包括2种情况。一种是JAVA类库内置的语义检查。例如数组下标越界,会引发IndexOutOfBoundsException;访问null的对象时会引发NullPointerException。另一种情况就是JAVA允许程序员扩展这种语义检查,程序员可以创建自己的异常,并*选择在何时用throw关键字引发异常。所有的异常都是java.lang.Thowable的子类。
102.Java的接口和C++的虚类的相同和不同处。
答案:由于Java不支持多继承,而有可能某个类或对象要使用分别在几个类或对象里面的方法或属性,现有的单继承机制就不能满足要求。与继承相比,接口有更高的灵活性,因为接口中没有任何实现代码。当一个类实现了接口以后,该类要实现接口里面所有的方法和属性,并且接口里面的属性在默认状态下面都是public static,所有方法默认情况下是public.一个类可以实现多个接口。
103.垃圾回收的优点和原理。并考虑2种回收机制。
答案:
Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。
104.描述一下你最常用的编程风格。
答案:****************************************
105.heap和stack有什么区别。
答案:栈是一种线形集合,其添加和删除元素的操作应在同一段完成。栈按照后进先出的方式进行处理。
堆是栈的一个组成元素
106.Static Nested Class 和 Inner Class的不同,说得越多越好(面试题有的很笼统)。
答案:Nested Class (一般是C++的说法),Inner Class (一般是JAVA的说法)。Java内部类与C++嵌套类最大的不同就在于是否有指向外部的引用上。
注:静态内部类(Inner Class)意味着1创建一个static内部类的对象,不需要一个外部类对象,2不能从一个static内部类的一个对象访问一个外部类对象
107.JAVA类实现序列化的方法?在collection中,实现比较要实现什么样的接口?
答案:
java类实现序列化需要实现java.io.Serializable接口。
在collection中实现比较要实现java.lang.Comparable接口或java.util.Comparator接口。