JAVA基础知识

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值