重载和重写的区别
重载:发生在同一个类中,方法名必须相同,参数类型不同,个数不同,顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。
重写:发生在父子类中,方法名,参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为private则子类就不能重写该方法。
String,StringBuffer,StringBuilder的区别是什么?String为什么是不可变的。
可变性
简单来说,String类中使用final关键字字符数保存字符串,private final char value[] ,所以String对象是不可变得。而StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串char[] value 但是没有用final关键字修饰,所以这两种对象都是可变的。
StringBuilder与StringBuffer的构造方法都是调用父类构造方法也就是AbstractStringBuilder实现的,大家可以自行查阅源码。
线程安全性
String中的对象是不可变得,也就可以理解为常量,线程安全。AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity,append,insert,indexOf等公共方法。StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的,StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。
性能
每次对String类型进行改变的时候,都会生成一个新的String对象,然后将指针指向新的String对象,StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用StringBuilder相比使用StringBuffer仅能获得10%~15%左右的性能提升,但却要冒多线程不安全的风险。
对于三者使用的情况的总结
1,操作少量的数据 = String
2,单线程操作字符串缓冲区下操作大量数据 = StringBuilder
3,多线程操作字符串缓冲区下操作大量数据 = StringBuffer
自动装箱与拆箱
装箱:将基本类型用它们对应的引用类型包装起来
拆箱:将包装类型转为基本数据类型
==与euqals
==:它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象。(基本数据类型比较的是值,引用数据类型比较的是内存地址)
equals():它的作用也是判断两个对象是否相等。但他一般有两种使用情况;
情况一类没有覆盖equals()方法。则通过equals()比较该类的两个对象时,等价于通过“==”比较这两个对象。
情况二类覆盖了equals()方法。一般,我们都覆盖equals()方法来比较两个对象的内容相等与否,若内容相等则返回true。
说明:
String中的equals方法是被重写过的,因为object的equals方法是比较的对象的内存地址,而string 的equals方法是比较对象的值
当创建String类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个String对象。
关于final关键字的一些总结
final关键字主要用在三个地方,变量,方法,类
1,对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
2,当用final修饰一个类时,表明这个类不能被继承,final类中的所有成员方法都会被隐式的指定为final方法
3,使用final方法的原因有两个,第一个原因是把方法锁定,以防任何继承类修改它的含义,第二个原因是效率,在早期的java实现版本中,,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升,(现在的java版本已经不需要final方法进行这些优化了)。类中所有的private方法都隐式地指定为final、
2.1.6 Object类的常见方法总结
public boolean equals(Object obj)//用于比较2个对象的内存地址是否相等,String类对该方法进行了重写用户
比较字符串的值是否相等。
public String toString()//返回类的名字@实例的哈希码的16进制的字符串。建议Object所有的子类都重写这个方
法
protected void finalize() throws Throwable { }//实例被垃圾回收器回收的时候触发的操作
java中异常处理
Java异常类层次结构图
在Java中,所有的异常都有一个共同的祖先Java.lang包中的Throwable类。Throwable:有两个重要子类。
**Error(错误)**是程序无法捕获处理的错误,大多是应用程序中的严重问题,与代码编写者执行的操作无关,而是jvm运行时的问题,如:堆栈溢出的OOM问题,发生时,jvm一般会选择线程终止。
**Exception(异常)**是程序本身可以捕获并处理的异常,Exception类有一个重要的子类RuntimeException。RuntimeException异常由Java虚拟机抛出。NullPointerException(要访问的变量没有引用任何对象时,抛出该
异常)、ArithmeticException(算术运算异常,一个整数除以0时,抛出该异常)和
ArrayIndexOutOfBoundsException (下标越界异常)。
注意:异常和错误的区别:异常能被程序本身可以处理,错误无法处理
Throwable类常用方法
public string getMessage():返回异常发生时的详细信息
public string toString():返回异常发生时的简要描述
public string getLocalizedMessage():返回异常对象的本地化信息。使用Throwable的子类覆盖这个方法,可
以声称本地化信息。如果子类没有覆盖该方法,则该方法返回的信息与getMessage()返回的结果相同
public void printStackTrace():在控制台上打印Throwable对象封装的异常信息
异常的处理
try块 用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。
catch: 用于处理try捕获到的异常。
finally: 无论是否捕获,都必须要执行的语句代码,当 try 块或 catch 块中遇到return语句时,finally语句块将在方法返回之前被执行。
以下四种情况finally不会被执行
1,在finally语句块中发生了异常
2,在前面的代码中用了System.exit()退出程序
3,程序所在的线程死亡。
4,关闭CPU。
获取用键盘输入常用的的两种方法
接口和抽象类的区别是什么
1,接口的方法默认时public,所有方法在接口中不能有实现(java8开始接口方法可以有默认实现,)抽象类可以有非抽象的方法
2,接口中的实例变量默认实final类型的,而抽象类中则不一定
3,一个类可以实现多个接口,但最多只能实现一个抽象类
4,一个类要实现接口的话,要实现接口的所有方法,而抽象类不一定
5,接口不能用new实例化,但可以声明,但是必须引用一个实现该接口的对象,从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。
备注:在JDK8中,接口也可以定义静态方法,可以直接用接口名调用。实现类和实现是不可以调用的。如果同时实现
两个接口,接口中定义了一样的默认方法,必须重写,不然会报错。