java面试宝典书籍-JavaSE基础

知识:java面试宝典  

JavaSE基础  注:知识都来源于Java面试宝典书籍,此处只为学习

一、Java面向对象      Standard Edition

1. 面向对象的特性以及理解

2. 访问修饰符

  • public 
  • protected
  • default
  • private
权限修饰符
修饰符 当前类 同包 子类 其他包
public true true true true
protected true true true false
default true true false false
private true false false false

 

 

 

 

 

 

3. clone

使用场景:当对象A需要多次调用,而在此期间,需要修改A的一些值但又不想要影响后面A对象的原值,这时就需要将A复制一份

4. new和clone的区别

  • 共同点:都能创建对象,同时分配内存
  • 不同点:clone不会调用构造方法,new会调用构造方法;clone()能快速创建一个已有对象的副本,即创建对象并且将已有对象中所有属性值克隆;new只能在JVM中申请一个空的内存区域,对象的属性值要通过构造方法赋值

5. clone对象的使用

// 复制引用

Person p1 = new Person();
Person p2 = p1;

System.out.println(p1);
System.out.println(p2);

// 结果:打印输出两个值一样,说明指向同一个对象,这是复制引用操作

// -------------------------------------------------------------

// 复制对象

Person p1 = new Person();
Person p2 = (Person) p1.clone();

System.out.println(p1);
System.out.println(p2);

// 结果:输出两个不同的值,说明指向的是不同的对象,这是clone操作

6. 深拷贝和浅拷贝

  • 默认的Object.clone()方法,对于引用类型成员变量拷贝只是拷贝“值”即地址,没有在堆中开辟新的内存空间
  • 重写clone()方法,对于引用类型成员变量,重新在堆中开辟新的内存空间

 

二、JavaSE语法

1. Java中有无goto语句

goto在Java中是保留字,目前还未在java中使用;还有一个保留字是const,在系统类库中使用过的有特殊意义的单词或单词的组合都被视为保留字

2. &和&&

  • &:按位与
  • &&:逻辑与

3. 跳出当前的多重嵌套循环

在最外层循环前加一个标记A,然后使用break A;可以跳出多重循环(break可跳出当前循环)。注:最好不要使用多重嵌套循环,这会使得程序变得复杂

4. equals和hashCode

  • 如果两个对象相同(equals 方法返回 true),那么它们的 hashCode 值一定要相同;如果两个对象的 hashCode 相同,它们并不一定相同。注:对于使用哈希存储的系统,如果哈希码频繁的冲突将会造成存取性能急剧下降)

  • equals:自反性、对称性、传递性、一致性;而且对于任何非 null 值的引用 x,x.equals(null)必须返回 false

  • 高效equals:1) 使用==操作符检查"参数是否为这个对象的引用"  2) 使用 instanceof 操作符检查"参数是否为正确的类型"  3) 对于类中的关键属性,检查参数传入对象 的属性是否与之相匹配  4) 编写完 equals 方法后,问自己它是否满足对称性、传递性、一致性  5) 重写 equals 时总是要重写 hashCode  6) 不要将 equals 方法参数中的 Object 对象替换为其他的类型,在重写时不要忘掉@Override 注解     

  • “重写”时想到了排序--compare

//实现Comparator进行排序
Collections.sort(stuList,new Comparator<Object>(){
    @Override
    public int compare(Object o1, Object o2) {
        return ((Student) o2).getAge() - ((Student) o1).getAge();
    }
});

5. String--引用数据类型,属于final类,无法被继承

6. 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

java方法调用只支持参数的值传递。场景:在javaweb中写Service层时候,从传入的数据数据封装为对象,即方法类的参数多为对象,可以在实现层去改里面的参数,但是其他方法的参数对象里面的属性值并未改变也不需要改变。

7. overload和override

  • 重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问

8. overload不能根据返回类型来区分

函数的返回值只是作为函数运行之后的一个“状态”,它是保持方法的调用者与被调用者进行通信的关键。并不能作为某个方法的“标识”,因为调用时不能指定类型信息,编译器不知道你要调用哪个函数。

9. char型变量中可以存储一个中文汉字

java使用的编码为unicode编码,char占两个字节,而一个汉字占两个字节

10. 抽象类(abstract class)和接口(interface)

相同:

  • 不能够实例化

  • 可以将抽象类和接口类型作为引用类型 、

  • 一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现,否则该类仍然需要被声明为抽象类

不同:

抽象类:

  • 抽象类中可以定义构造器
  • 可以有抽象方法和具体方法
  • 接口中的成员全都是 public 的
  • 有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法
  • 抽象类中可以包含静态方法
  • 一个类只能继承一个抽象类

接口:

  • 接口中不能定义构造器
  • 方法全部都是抽象方法
  • 抽象类中的成员可以是 private、默认、protected、public
  • 接口中定义的成员变量实际上都是常量
  • 接口中不能有静态方法
  • 一个类可以实现多个接口
public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   public Employee(String name, String address, int number)
   {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }
   public double computePay()
   {
     System.out.println("Inside Employee computePay");
     return 0.0;
   }
   public void mailCheck()
   {
      System.out.println("Mailing a check to " + this.name
       + " " + this.address);
   }
   public String toString()
   {
      return name + " " + address + " " + number;
   }
   public String getName()
   {
      return name;
   }
   public String getAddress()
   {
      return address;
   }
   public void setAddress(String newAddress)
   {
      address = newAddress;
   }
   public int getNumber()
   {
     return number;
   }
}
interface Animal {
   public void eat();
   public void travel();
}

11. 抽象的(abstract)方法是否可同时是静态的(static), 是否可同时是本地方法(native),是否可同时被 synchronized都不能。抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。本地方法是由 本地代码(如 C 代码)实现的方法,而抽象方法是没有实现的,
也是矛盾的。synchronized 和方法的实现细节有关, 抽象方法不涉及实现细节,因此也是相互矛盾的。https://www.cnblogs.com/ibelieve618/p/6410910.html    作者:自学开发的老司机 

12. 静态变量和实例变量

  • 静态变量:是被 static 修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝
  • 实例变量:必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存

13. == 和 equals

  • ==:运算符。如果比较的是基本数据类型,则比较的是基本类型的值;如果比较的是对象,则比较的是地址值
  • equals:方法。不能用于基本数据类型的变量,如果没有对equals()进行重写,则比较的是引用类型的变量所指向的对象的地址

14. break和continue

  • break:跳出一个循环
  • continue:跳出本次循环,执行下一次循环

15. String s = "Hello";s = s + " world!";这两行代码执行后,原始的String对象中的内容到底变了没有?

没有。因为 String 被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。在这段代码中,s 原先指 向一个 String 对象,内容是 "Hello",然后我们对 s 进行了“+”操作,那么 s 所指向的那个对象是否发生了改变呢? 答案是没有。这时,s 不指向原来那个对象了,而指向了另一个 String 对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是 s 这个引用变量不再指向它了。           StringBuffer

三、Java中的多态

1. Java实现多态的机制

靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。

// 多态,通过父类指向具体子类的实例对象
Animal dog = new Dog();

四、Java的异常处理

1. Java中异常处理分为那些类

  • 编译时异常--CheckedException(强制性异常):Java 程序必须显式处理 Checked 异常。如果程序没有处理 Checked 异常,该程序在编译时就会发生错误无法编译。处理方法:1) 当前方法知道如何处理该异常,则用 try...catch 块来处理该异常 2) 当前方法不知道如何处理,则在定义该方法时声明抛出该异常
  • 运行时异常--RuntimeException(非强制性异常):只有当代码在运行时才发行的异常,编译时不需要 try catch

2. 

public int getNum(){
    try {
        int a = 1.0 / 0;
        return 1;
    } catch (Exception e){        
        return 2;
    } finally {
        return 3;
    }
}

// 最终结果:返回值为3

3. error和exception--Error 类和 Exception 类的父类都是 Throwable 类

  • Error 类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢出等。对于这类 错误的导致的应用程序中断,仅靠程序本身无法恢复和和预防,遇到这样的错误,建议让程序终止

  • Exception 类表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常--又与异常类相联系        系统异常和普通异常

4. Java异常处理类机制

  • 所有的异常的根类:java.lang.Throwable    有Error和Exception两个类

5. 5个常见的异常

  • java.lang.NullPointerException 空指针异常;出现原因:调用了未经初始化的对象或者是不存在的对象

  • java.lang.ClassNotFoundException 指定的类找不到;出现原因:类的名称和路径加载错误;通常都是程序试图通过字符串来加载某个类时可能引发异常

  • java.lang.NumberFormatException 字符串转换为数字异常;出现原因:字符型数据中包含非数字型字符

  • java.lang.IndexOutOfBoundsException 数组角标越界异常,常见于操作数组对象时发生

  • java.lang.IllegalArgumentException 方法传递参数错误

  • java.lang.ClassCastException 数据类型转换异常

  • java.lang.NoClassDefFoundException 未找到类定义错误

  • SQLException SQL 异常,常见于操作数据库时的 SQL 语句错误

  • java.lang.InstantiationException 实例化异常

  • java.lang.NoSuchMethodException 方法不存在异常

6. throw 和 throws

throw:

  • throw 语句用在方法体内,表示抛出异常,由方法体内的语句处理

  • throw 是具体向外抛出异常的动作,所以它抛出的是一个异常实例,执行 throw 一定是抛出了某种异常

throws:

  • throws 语句是用在方法声明后面,表示如果抛出异常,由该方法的调用者来进行异常的处理
  • throws 主要是声明这个方法会抛出某种类型的异常,让它的使用者要知道需要捕获的异常的类型
  • throws 表示出现异常的一种可能性,并不一定会发生这种异常

7. final、finally、finalize

  • final:用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,被其修饰的类不可继承

  • finally:异常处理语句结构的一部分,表示总是执行

  • finalize:Object 类的一个方法,在垃圾回收器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。该方法更像是一个对象生命周期的临终方法,当该方法 被系统调用则代表该对象即将“死亡”,但是需要注意的是,我们主动行为上去调用该方法并不会导致该对 象“死亡”,这是一个被动的方法(其实就是回调方法),不需要我们调用

五、JavaSE常用API

1. Math.round()--四舍五入

2. switch 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String 上?

Java5 以前 switch(expr)中,expr 只能是 byte、short、char、int。从 Java 5 开始,Java 中引入了枚举类型, expr 也可以是 enum 类型。 从 Java 7 开始,expr 还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的

3. 数组有没有 length() 方法?String 有没有 length() 方法?

数组没有 length()方法,而是有 length 的属性。String 有 length()方法。JavaScript 中,获得字符串的长度是通过 length 属性得到的,这一点容易和 Java 混淆

4. String、StringBuffer、StringBuilder

  • String 和 StringBuffer/StringBuilder,它们都可以储存和操作字符串

  • String 是只读字符串,也就意味着 String 引用的字符串内容是不能被改变的

  • StringBuffer/StringBuilder 表示的字符串对象可以直接进行修改

  • StringBuilder 是 Java5 中引入的,它和 StringBuffer 的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方法都没有被 synchronized 修饰,因此它的效率理论上也比 StringBuffer 要高

5. 什么情况下用“+”运算符进行字符串连接比调用 StringBuffer/StringBuilder对象的 append 方法连接字符串性能更好

  • String的"+"和StringBuilder/StringBuffer的append--在 Java 中无论使用何种方式进行字符串连接,实际上都使用的是 StringBuilder
  • 一般情况进行字符串拼接用+就可以,系统内部会进行优化,但是如果是循环拼接,则需要用StringBuilder的append来实现
        String str1 = "love";
        for(int i=0;i<10;i++)
        {
            //系统会在这里创建StringBuilder,然后进行append,这样会增加内存消耗
            str1 += i;
        }
        //StringBuilder
        StringBuilder str2 = new StringBuilder("love2");
        for(int i=0;i<10;i++)
        {
            //这里的StringBuilder是在外部创建的,就一个,所以不会增加内存消耗
            str2.append(i);
        }

6.

class StringEqualTest {
public static void main(String[] args) {
    String s1 = "Programming";
    String s2 = new String("Programming");
    String s3 = "Program";
    String s4 = "ming";
    String s5 = "Program" + "ming";
    String s6 = s3 + s4;
    System.out.println(s1 == s2); //false
    System.out.println(s1 == s5); //true
    System
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值