一、重载和重写的区别
Overload重载:同一个类中,出现的方法名相同,参数列表不同(参数类型,参数个数甚至是参数顺序)的现象,注意:不能通过返回值类型、访问权限、抛出异常进行重载
Override重写:在子类中,出现和父类中一模一样的方法声明的现象【返回值类型(可以是父类的子类)、方法名、参数列表相同】
注意:访问修饰符子类大于父类,抛出异常子类小于父类
总结
1、重写和重载都是多态的实现方式:重写实现了编译时的多态、而重载实现了运行时的多态
2、重载发生在同一个类中,同名方法参数列表不同(参数类型、参数个数、参数顺序至少一个不同),与返回类型、访问权限、抛出异常无关。
3、重写发生子类与父类之间,同名方法要求有相同的参数列表、返回类型(可以是父类的子类)、访问修饰符(不小于父类)、异常(不大于父类)
二、String,StringBuffer和StringBuilder的区别
1、可变性
(1)String类使用final关键字字符数组保存字符串,其对象不可变
public final class String
implements java.io.Serializable,
Comparable, CharSequence {
/** The value is used for character storage. */
private final char value[];
.......
}
(2)StringBuffer和StringBuilder类型都继承自AbstractStringBuilder,而AbstractStringBuilder中使用字符数组保存字符串,但没有final修饰,因此StringBuffer和StringBuilder类型的对象是可变的。他们的构造函数都是调用父类AbstractStringBuilder的构造函数实现的。
//AbstractStringBuilder的部分源码
abstract class AbstractStringBuilder implements Appendable, CharSequence {
char[] value;//The value is used for character storage.
int count;//The count is the number of characters used.
//This no-arg constructor is necessary for serialization of subclasses.
AbstractStringBuilder() { }
//Creates an AbstractStringBuilder of the specified capacity.
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
}
//StringBuilder的部分源码
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
public StringBuilder() {
super(16);
}
.......//其他源码省略
}
//StringBuffer的部分源码
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
public StringBuffer() {
super(16);
}
.......//其他源码省略
}
2、线程安全性
(1)String类型的对象不可变,可类似于常量,线程安全
(2)StringBuffer对方法加了同步锁,线程安全。源码中可看到所有方法都加了关键字synchronized
public final class StringBuffer{
public synchronized int length() {
return count;
}
public synchronized int capacity() {
return value.length;
}
.......//其他源码省略
}
(3)StringBulider中的方法没有加同步锁,因此是线程不安全的。
3、运行速度
(1)String类型的引用重新赋值时,都需要在字符串常量池生成一个新的String对象,然后将新的引用返回。
(2)StringBuffer因为线程安全的原因,其运行速度会比StringBuilder稍慢。
因此,StringBuilder > StringBuffer > String
4、适用情况
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
三、自动装箱与拆箱
自动装箱:将基本类型包装成对应的引用类型
Integer num=66;//自动装箱
//反编译得到的结果如下:
Integer num = Integer.valueOf(66);
自动拆箱:将包装类型转换为基本的数据类型
int M=num;//自动拆箱
//反编译得到的结果如下:
int M=num.intValue();
四、接口和抽象类的区别
抽象类不能创建实例,它只能作为父类被继承。抽象类是从多个具体类中抽象出来的父类,它具有更高层次的抽象。
接口中的成员变量默认public static final;成员方法默认public abstract;没有构造方法。
抽象类与接口的区别
接口和抽象类最大的一个区别,就在于抽象类可以提供某些方法的部分实现,而Java接口不可以
五、==和equals的异同
==:对于基本数据类型,比较的是值是否相等;对于引用数据类型,比较的是内存地址是否相同,即是否是同一个对象
equals():如果类重写了equals方法,那么一都判断对象的内容是否相等;如果类没有重写equals方法,那么等同于"=="
String a=new String("str");
String b=new String("str");
String aa="str",bb="str";
System.out.println(a==b);//false,a和b不是同一个对象
System.out.println(a.equals(b));//true,a和b指向地址的内容相等
System.out.println(aa==b);//false,aa和b指向不同
System.out.println(aa==bb);//true,a和b都指向字符串常量池中的"str"
六、final关键字的用法
1、修饰变量时,只有在定义和构造函数中才可以进行初始化,一旦初始化,不能更改
如果是基本数据类型,则数值初始化后不能更改
如果是引用类型变量,初始化后不能再指向另一个对象
public class FinalTest1 {
private final int i = 3; //定义时初始化
private final int j;
public FinalTest1() { //构造函数中初始化
j = 3;
}
}
2、修饰方法时,方法不能被重写。类中的private方法会隐式的被指定为final方法。
3、修饰类时,类无法被继承,所有成员方法隐式指定为final方法
七、Object类的常见方法
// native方法,用于返回当前运行时对象的cl ass对象,使用了 final关键字修饰,故不允许子类重写。
public final native class> getclass ()
//native方法,用于返回对象的哈希码,主要使用在哈希表中,比如]DK中的 HashMap()
public native int hashcode()
//用于比较2个对象的内存地址是否相等,string类对该方法进行了重写用于比较字符串的值是否相等。
public boolean equals(Object obj)
//naitive方法,用于创建并返 回当前对象的一份拷贝。
—般情况下,对于可对象x,表达式x.clone() != x为true, x.clone().getclass() == x.getclass() 为true。
实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。
protected native object clone() throws cloneNotSupportedException
用途:JAVA里除了8种基本类型传参数是值传递,其他的类对象传参数都是引用传递,我们有时候不希望在方法里讲参数改变,这是就需要在类中复写clone方法。
//返回类的名字@实例的哈希码的16进制的字符串。建议object所有的子类都重写这个方法。
public string toString()
//native方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果有多个线程在等待只会任意唤醒一个。
public final native void notify()
//native方法,并且不能重写。跟notify—样,唯一的区别就是会唤醒此对象监视器上等待的所有进程,而不是一个线程。
public final native void notifyAll()
//native方法,并且不能重写。暂停线程的执行。注意:sleep方法没有释放锁,而wait方法释放了锁。timeout是等待时间。
public final native void wait(long timeout) throws lntemjptedException
//多了 nanos 参数,这个参数表示额外时间(以毫微秒为单位,范围是0-999999)。所以超时的时间还需要加上nanos毫秒。
public final void wait (long timeout, int nanos) throws interruptedException
//跟之前的2个wait方法一样,只不过该方法一直等待,没有超时时间这个概念
public final void wait() throws lnterruptedException
//实例被垃圾回收器回收的时候触发的操作
protected void finalizeO throws Throwable {}
八、获取输入的三种方法
1、通过java.util.Scanner类(最常用)
while (true){
Scanner sc = new Scanner(System.in);
if (sc.hasNextInt()){
....
}else {
System.out.println("Error!");
}
}
2、通过java.util.BufferedReader类
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
String s = br.readLine();
System.out.println(s);
} catch (IOException e) {
e.printStackTrace();
}
3、仅获取单个字符
try {
char c = (char)System.in.read();
System.out.println(c);
} catch (IOException e) {
e.printStackTrace();
}
九、Java的异常处理
Java的异常类层次结构图
Throwable类是所有异常的父类,它包含两大子类:Exception(异常)和Error(错误)
1、Error (错误):是程序无法处理的锗误,表示运行应用程序中较严重问题。
大多数错误与代码编写者执行的操作无关,而表示代码运行时JVM(Java虚拟机)出现的问题。例如,Java虚拟机运行错误(VirtualMachineError),当 JVM不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。
这些错误表示故障发生于虚拟机自身、或者发生在虚拟机试图执行应用时,如Java虚拟机运行错误(Virtual MachineError)、类定义错误(NoClassDefFoundError)等。这些错误是不可査的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。
对于设计合理的应用程序来说,即使确实发生了错误,本质上也不应该试图去处理它所引起的异常状况。在java中,错误通过Error的子类描述。
2、Exception (异常):是程序本身可以处理的异常。
Exception类有一个重要的子类RuntimeException。
RuntimeException异常曲ava虚拟机抛出。NullPointerException (要访问的变量没有引用可对象时,抛出该异常)、ArithmeticException (算术运算异常,一个整数除以0时,抛出该异常)和ArraylndexOutOfBoundsException (下标越界异常)。
注意:异常和错误的区别:异常能被程序本身可以处理,错误是无法处理。
3、Throwable类常用方法
public string getMessage():返回异常发生时的详细信息
public string toString():返回异常发生时的简要描述
public string getLocalizedMessage():返回异常对象的本地化信息。使用Throwable的子类覆盖这个方法,可以声称本地化信息。如果子类没有覆盖该方法,则该方法返回的信息与getMessage ()返回的结果相同
public void printStackTrace():在控制台上打印Throwable对象封装的异常信息
4、异常处理总结
(1)try-catch-finally
try块:用于捕获异常,其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块
catch块:用于处理try捕获到的异常。
finally块:无论是否捕获或处理异常,finally里的语句都会被执行,当在try块或catch块中遇到return时,finally语句块将在方法返回之前被执行。
(2)finally不被执行的情况
在finally语句块中发生了异常。
在前面的代码中用了System.exit()退出程序。
程序所在的线程死亡。
关闭CPU。
//finally中没有return
public class Main {
public static void main(String[] args) {
System.out.println("最终返回值:x="+method());
}
public static int method() {
int x=0;
try {
x=20;
System.out.println(1/0);
System.out.println("try块:x="+x);
return x;
}catch(Exception e) {
x=30;
System.out.println("catch块:x="+x);
return x;
}finally {
x=60;
System.out.println("finally块:x="+x);
//return x;
}
}
}
finally中没有return时,返回catch中的x值
public class Main {
public static void main(String[] args) {
System.out.println("最终返回值:x="+method());
}
public static int method() {
int x=0;
try {
x=20;
System.out.println(1/0);
System.out.println("try块:x="+x);
return x;
}catch(Exception e) {
x=30;
System.out.println("catch块:x="+x);
return x;
}finally {
x=60;
System.out.println("finally块:x="+x);
return x;
}
}
}
finally中有return时,返回finally中的x值