前面已经分享了两章Java面试基础知识,分别是《Java面试题–基础知识汇总》和《Java面试题–设计模式与继承多态》,这篇文章接着来分享Java面试的基础知识点。

多态

  • 同一个对象,在程序不同时刻的多种运行状态。举例:动物,狗是狗,狗是动物。水(气态,液态,固态)

  • 多态前提

    1. 存在着继承或者实现关系
    2. 有方法的重写
    3. 父类(接口)引用指向子类(实现)对象
  • 多态的好处和弊端:

  1. 好处:多态的存在提高了程序的扩展性和后期可维护性
  2. 弊端:虽然可以预先使用,但是只能访问父类中已有的功能,运行的是后期子类的功能内容。
    不能预先使用子类中定义的特有功能。
  • 多态中对象调用成员的特点
    Fu f = new Zi();
  1. 成员变量
    编译看左边,运行看左边
    1. 成员方法
      编译看左边,运行看右边
    2. 静态方法
      编译看左边,运行看左边
  • 多态的思想
    指挥同一批对象做事情。举例:带兵打仗,下课等。

Object类

  1. 是所有类的根类,超类。
    java中提供的类以及我们自定义的类都直接或者间接的继承自Object类。
  2. Object类中的方法
    1. void finalize()
      当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
    2. Class getClass()
      获取对象的字节码文件的描述类,后面再讲反射的时候还会在说这个类。
      String name = s.getClass().getName();
    3. int hashCode()
      获取对象的哈希值。其实就是对象的内存地址值十进制表示
    4. String toString()
      返回对象的字符串表示。
  3. 表示格式:
getClass().getName()+"@"+Integer.toHexString(hashCode());

一般我们输出对象名的时候,其实底层调用的就是该对象的toString()方法。
这种返回没有意义,所以,我们会重写这个方法,显示类的成员变量信息。

  • boolean equals(Object obj)
    用于比较两个对象的地址值是否相同。
    我们获取对象后,比较它的地址值意义不大。所以也会对这个方法进行重写。
    重写要完成什么功能,是根据需求定的。
  1. ==和equals的用法:

    1. ==怎么用?
      可以用于比较基本数据类型,比较的就是基本数据类型的值是否相等。
      可以用于比较引用数据类型,比较的是对象的地址值是否相等。

    2. equals怎么用?
      equals只能用于比较引用数据类型的。
      Object提供的equals是用于比较对象地址值是否相同。
      自定义类中,如果重写了equals方法,那么就是按照你自己的需求来比较的。

      一般我们输出对象名的时候,其实底层调用的就是该对象的toString()方法。
      这种返回没有意义,所以,我们会重写这个方法,显示类的成员变量信息。

    3. boolean equals(Object obj)
      用于比较两个对象的地址值是否相同。
      我们获取对象后,比较它的地址值意义不大。所以也会对这个方法进行重写。
      重写要完成什么功能,是根据需求定的。

  2. package关键字

    1. 包:其实就是文件夹。用于区分不同包下相同的类名。
    2. 好处:
      A:对类文件进行分类管理。
      B:给类提供了多层命名空间
      aaa.Demo
      bbb.Demo
      C:写在程序文件的第一行。
      D:包也是一种封装形式。
  3. import关键字

    1. 导入包的关键字
    2. 格式:
      import 包名;
    3. 注意:
      A:一个程序文件中只有一个package,可以有多个import。
      B:用来导包中的类,不导入包中的包。
      C:通常写import mypack.Demo,明确自己使用的类。
  • 关键字的顺序
    类,包,导包这些关键的顺序。
    包 – 导包 – 类

  • 不同修饰符的访问权限

            
    
    			本类中       同一个包中       不同包中的子类中        不同包中
    private OK
    默认 OK Ok
    protected OK Ok OK
    public OK Ok OK OK

  • 不同修饰符可以修饰哪些内容

       			   类            构造方法          成员变量              成员方法
    private (能修饰内部类) OK OK OK
    默认 Ok Ok Ok OK
    protected (能修饰内部类) OK OK Ok
    public Ok Ok OK OK
    static OK Ok
    final Ok OK OK
    abstract Ok OK
  • 一般格式:

    1. 成员变量:
      权限修饰符+static/final+数据类型+成员变量名
      public static final int NUM = 10;
    2. 成员方法:
      权限修饰符+static/final/abstract+返回类型+方法名

内部类(次重点)

把一个类定义在某个类中的,这个类就被称为内部类,内置类,嵌套类。

  1. 访问特点:
    A:内部类可以直接访问外部类中的成员,因为内部类持有外部类的引用,
    格式为:外部类名.this
    B:外部类要想访问内部类的成员,必须创建对象访问。

  2. 内部类的访问格式:

  • 当内部类定义在外部类的成员位置,而且非私有,则可以在其他外部类中直接建立内部类对象
    格式:外部类名.内部类名 变量名 = new 外部类对象.内部类对象
    如:Outer.Inner in = new Outer().new Inner()
  • 当内部类在外部类成员位置,且被static修饰时,外部其他类可直接访问静态内部类的非静态成员
    格式:new 外部类名.内部类名().内部类成员
    如:new Outer.Inner().function();
  • 外部其他类可直接访问静态内部类的静态成员
    格式:new 外部类名.内部类名.内部类成员
    如:new Outer.Inner.function();
  1. 什么使用时候内部类呢?

    假如有A类和B类,A类想直接访问B类的成员,B类访问A类成员的时候,需要创建A类对象进行访问,这个时候,就可以把A类定义为B类的内部类。

  2. 内部类的位置
    A:成员位置
    可以被private修饰(Body,Heart)
    可以被static修饰。(它访问的外部类的成员必须是静态的)
    B:局部位置
    可以直接访问外部类中的成员,因为还持有外部类的持用
    也可以直接访问局部成员,但是局部成员要用final修饰。
    注意:局部内部类不能用private和static修饰

  3. 通过class文件我们就可以区分是否带有内部类,以及内部类的位置
    Outer$Inner:成员内部类
    Outer$1Inner:局部内部类

  • 匿名内部类(局部内部类的简写) (重点)
    (1)前提:继承一个类或者实现一个接口
    (注意不要弄混匿名内部类的前提和多态的前提)
    (2)格式:

    new 父类名或者接口名()
    {
    重写父类方法或者实现接口中的方法。
    也可以自定义其他方法。
    };

什么时候定义匿名内部类?
匿名内部类只是为了简化书写,匿名内部类有局限,通常定义匿名内部类时,该类方法不超过3个

匿名内部类的好处和弊端:
好处:简化代码书写
弊端:
不能直接调用自己的特有方法
不能执行强转换动作
如果该类里面方法较多,不允许使用匿名内部类

  • 模板设计模式:
    在定义功能时,功能的一部分是确定的,有一部分是不确定的,而且确定的部分在使用不确定的部分,
    可将不确定的部分暴露出去,由该类的子类去完成。
    如:求一段程序的运行时间例子。

  • 异常
    (1)程序运行过程中的不正常现象就叫异常。
    (2)导致程序运行不正常的现象有很多,所以,就有很多的异常对象。
    而这些异常对象存在着共性的内容,所以,可以不断的进行抽取。最终形成了异常的体系结构。
    异常体系的根类是:Throwable

     Throwable:
    |--Error:重大的问题,我们处理不了。也不需要编写代码处理。比如说内存溢出。
    |--Exception:一般性的错误,是需要我们编写代码进行处理的。
    |--RuntimeException:运行时异常,这个我们也不需要处理。
    其实就是为了让他在运行时出问题,然后我们回来修改代码。



    + 异常的分类
    异常有两种:
    编译时被检测异常:
    该异常在编译时,如果没有处理(没有抛也没有try),编译失败。
    该异常被标识,代表这可以被处理。
    运行时异常(编译时不检测)
    在编译时,不需要处理,编译器不检查。
    该异常的发生,建议不处理,让程序停止。需要对代码进行修正。

    + **(4)异常体系的特点:**
    异常体系中的所有类及其子类对象都具备可抛性。也就是说可以被throw和throws关键字所操作。

    + **(5)main方法是如何处理异常的。**
    A:在main里面编写代码进行处理
    B:交给jvm自己进行处理。采用的是jvm的默认处理方式。
    其实就是相当于调用了异常对象的printStackTrace()方法。

    + **(6)Throwable类的学习**
    getMessage():获取异常信息,返回字符串。
    toString():获取异常类名和异常信息,返回字符串。
    printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。

    + **(7)异常的处理·**

          A:try...catch...finally

    基本格式:

        try
        {
        可能出现异常的代码
        }
        catch(异常对象)
        {
        异常处理代码
        }
        finally
        {
        释放资源
        }

    变形格式:

        try...catch
        try...catch...catch...
        try...catch...catch...finally

    多个异常同时被捕获的时候,记住一个原则:
    先逮小的,再逮大的。
    finally:永远被执行,除非退出jvm。System.exit(0);

    #### 面试题2个

    **final,finally,finalize区别?**
    final是最终的意思。它可以用于修饰类,成员变量,成员方法。
    它修饰的类不能被继承,它修饰的变量时常量,它修饰的方法不能被重写。<br/
    finally:是异常处理里面的关键字。
    它其中的代码永远被执行。特殊情况:在执行它之前jvm退出。System.exit(0);<br/
    finalize:是Object类中的一个方法。
    它是于垃圾回收器调用的方式。

    :假如catch中有return语句, finally里中的代码会执行吗?
    是在return前,还是在return后呢?
    会,在return前执行finally里面的代码。
    (8)Exception和RuntimeException的区别
    A:Exception:一般性的错误,是需要我们编写代码进行处理的。
    B:RuntimeException:运行时异常,这个我们也不需要处理。
    其实就是为了让他在运行时出问题,然后我们回来修改代码。
    在用throws抛出一个的时候,如果这个异常是属于RuntimeException的体系的时候,
    我们在调用的地方可以不用处理。(RuntimeException和RuntimeException的子类)
    在用throws抛出一个的时候,如果这个异常是属于Exception的体系的时候,
    我们在调用的地方必须进行处理或者继续抛出。

    + **自定义异常**
    定义类继承Exception或者RuntimeException
    1. 为了让该自定义类具备可抛性。

    2. 让该类具备操作异常的共性方法。

    class MyExcepiton extends Exception {

               MyExcepiton(){}   
               MyExcepiton(String message)  
              {    super(message);    } 
          } 
          class MyException extends RuntimeException  {
              MyExcepiton(){}  
            MyExcepiton(String message) 
             {    super(message);    } 
           }
    
    

  • throws和throw的区别
    A:有throws的时候可以没有throw。
    有throw的时候,如果throw抛的异常是Exception体系,那么必须有throws在方法上声明。
    B:throws用于方法的声明上,其后跟的是异常类名,后面可以跟多个异常类,之间用逗号隔开
    throw用于方法体中,其后跟的是一个异常对象名

码字不易,求分享、转发。😄

推荐阅读