String 和 StringBuffer、StringBuilder 的区别是什么?String 为什么是不可变的?
可变性:
简单来说String类中使用final关键字字符数组保存字符串,private final char value【】,所以string对象是不可变的。
而StringBuffer,StringBuilder都继承自AbstractStringBuilder类,在AbstractStringBuilder也是使用字符数组来保存字符串 char【】value但是没有使用final关键字修饰,所以这两种对象是可变的。(StringBuilder 与 StringBuffer 的构造方法都是调用父类构造方法也就是 AbstractStringBuilder 实现的。)
线程安全性:
String是不可变的常量所以是安全的,AbstractStringBuilder是StringBuilder与StringBuffer的父类,定义了一些字符串的基本操作,如expendCapacity,append,insert,indexOf,等公共方法。StringBuffer对方法或调用的方法加了同步锁所以线程是安全的,StringBuilder没有对方法加同步锁所以是非线程安全的。
性能:
每次对String对象进行修改都要生成一个新的对象,并让指针指向新的对象。而对StringBuffer对象修改时只需对对象本身进行操作,而不需要将指针指向新的对象。相同情况下用StringBuilder会比用StringBuffer的性能提升10%-15%,但会面临着多线程不安全的风险。
对三者的总结:
操作少量数据=string
单线程操作字符串缓冲区下操作大量数据=StringBuilder
多线程操作字符串缓冲区下操作大量数据=StringBuffer
装箱:将基本数据类型用它们对应的引用类型包装起来
拆箱:将包装的类型转换为基本的数据类型
关于final的一些总结:
对于一个final变量,如果修饰的是基本数据类型那么在初始化后就不能被修改,如果修饰的是引用变量,则在初始化后不能指向其他的对象。
final修饰一个类时,这个类就不能被继承,它的所有成员方法都被隐性地指定为final。
使用final的原因,一是把方法锁定,以防任何继承类修改它的定义,二是效率。
类中所有的private方法都隐式地指定为fianl。
JAVA的异常处理
在JAVA中,所有的异常都有一个共同的祖先Java.lang中的Throwable类。Throwable类下有两个重要的子类,Exception(异常)和Error(错误),各自都包含着大量的子类。
获取用键盘输入的常用两种方法:
通过scanner
Scanner input = new scanner(System.in);
String s = input.nextLine();
input.close;
通过BufferedReader
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String s = input.readLine();
接口和抽象类的区别?
接口的方法默认是public,所有的方法在接口中都不能实现(JAVA8中方法可以有默认实现),抽象类可以有非抽象的方法。
接口中实例变量默认是final类型,而抽象类不一定。
一个类可以实现多个接口,但只能实现一个抽象类
一个类实现接口就需要实现接口所有的方法,而抽象类不一定。
接口不可以用new实例化,但可以声明,但必须引用一个实现该接口的对象。从设计层面上说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是行为的规范。
Vector与Arrlist的区别
Vector类上的所有方法都是是同步的,可以由两个线程安全的访问Vector类的一个对象,但一个线程访问时代价较大。
arrlist不是同步的,在不要求线程安全时建议使用arrlist
Hashmap的底层实现?
JDK1.8之前是链表和数组的结合,即链表散列。
JDK1.8之后是红黑树
JAVA包:
将功能相似或相关的类或接口封装起来装在一个包中,方便查找和使用。
如同文件夹一样包也采用了树形目录的存储方式,不同的包中可以有相同的类名,当同时调用不同包中相同的类名的类时应该加上包名加以区分,避免名字冲突。
包也限定了访问权限,拥有访问权限的类才能访问某个包中的类。
JAVA的继承
子类所有构造方法的内部第一行会默认(隐式)地使用Super()调用父类无参的构造方法,若子类构造函数第一行显示地调用父类构造方法,则JAVA虚拟机不会自动调用无参的Super()。
class Base {
public Base() {
System.out.println("Base--默认构造方法");
}
public Base(int c){
System.out.println("Base--有参构造方法--" + c);
}
}
public class Derived extends Base {
public Derived() {
// super(); //系统会自动隐式先调用父类的无参构造函数 super(); //必须是第一行,否则不能编译
System.out.println("Derived--默认构造方法");
}
public Derived(int c) {
// super(); //系统会自动隐式先调用父类的无参构造函数 super(); //必须是第一行,否则不能编译
System.out.println("Derived--有参构造方法" + c);
}
public Derived(int a, int b) {
super(a); //如果子类构造方法第一行显式调用了父类构造方法,系统就不再调用无参的super()了。
System.out.println("Derived--有参构造方法--" + b);
}
public static void main(String[] args) {
System.out.println("============子类无参============");
Derived no = new Derived();
System.out.println("============子类有参============");
Derived have = new Derived(33);
System.out.println("============子类有参============");
Derived have2 = new Derived(33, 55);
}
}
输出结果:
============子类无参============
Base--默认构造方法
Derived--默认构造方法
============子类有参============
Base--默认构造方法
Derived--有参构造方法33
============子类有参============
Base--有参构造方法--33
Derived--有参构造方法--55
/*注意:如果父类没有无参构造函数,创建子类时,不能编译,除非在构造函数代码体中的第一行显式调用父类有参构造函数。*/
Object类是所有类的直接父类或间接父类,也就是说是所有类的根父类,这个可以运用于参数的传递
如下:
public class Start
{
public static void main(String[] args)
{
A a=new A();
B b=new B();
C c=new C();
D d=new D();
speak(a);
speak(b);
speak(c);
speak(d);
}
// instanceof 关键字是用于比较类与类是否相同,相同返回true,不同返回false
//当你不清楚你需要的参数是什么类型的,可以用Object来代替,Object可以代替任何类
static void speak(Object obj)
{
if(obj instanceof A)//意思是:如果参数是 A 类,那么就执行一下语句
{
A aobj=(A)obj;//这里是向下转换,需要强制转换
aobj.axx();
}
else if(obj instanceof B)
{
B bobj=(B)obj;
bobj.bxx();
}
else if(obj instanceof C)
{
C cobj=(C)obj;
cobj.cxx();
}
}
}
//这里举了四个类,他们的函数都不同,但都是 Object 类的子类
class A
{
void axx()
{
System.out.println("Good morning!");
System.out.println("This is A");
}
}
class B
{
void bxx()
{
System.out.println("Holle!");
System.out.println("This is B");
}
}
class C
{
void cxx()
{
System.out.println("Look!");
System.out.println("This is C");
}
}
class D
{
void dxx()
{
System.out.println("Oh!Bad!");
System.out.println("This is D");
}
}
运行结果:
Good morning!
This is A
Holle!
This is B
Look!
This is C