Java小李备春招|面向对象

Java小李备春招|面向对象

Java小李备春招系列文章:
1. Java小李备春招|JVM
2. Java小李备春招|面向对象
3. Java小李备春招|常用API
4. Java小李备春招|异常
5. Java小李备春招|集合
6. Java小李备春招|IO
7. Java小李备春招|计算机网络

  1. 面向对象可以解释一下吗?都有哪些特性?

    面向对象是一种思想,可以将复杂的问题简单化。主要是把构成问题的各个事物分解成对象,建立对象的目的不是为了完成一个步骤,而是为了描述一个事物在解决问题的过程中经历的步骤和行为。面向对象具有三大特性:封装、继承、多态。

  2. 简要描述面向对象的三大特性。
    面向对象具有三大特性:封装、继承和多态。

    封装是指将对象的属性和实现细节隐藏起来,只提供公共的访问方式。
    好处:(1)将外界的变化隔离开,使程序具备独立,安全和稳定性。
    (2)便于设计者使用,提高了代码的复用性。
    (3)设置访问权限可以限定该功能或属性被特定的访问者访问,保证了程序的安全性和功能的稳定性。

    继承是从已有的类派生出新的类,新的类能继承已有类的数据属性和行为,并扩展新的功能。
    好处:继承的好处是实现代码的复用以及扩展,子类通过对父类代码的复用,可以不用再定义父类中已经定义的成员变量,方法上直接对父类的方法进行重写实现了扩展。

    多态是不同对象对同一行为的不同表现形式
    前提:继承、重写、父类引用指向子类对象(只能调用父类下有的方法,实现结果是子类重写后的结果)
    好处:提高了代码的可扩展性,派生类的功能可以被父类的方法或引用变量所调用,提高了代码的扩展性和灵活性。
    弊端:父类引用无法调用子类的特有内容。

  3. 成员变量和局部变量的区别。
    1)在类中的位置不同:
    成员变量在类中,方法外。
    局部变量在方法声明上,方法中。
    2)在内存中的位置不同:
    成员变量属于对象,进堆内存。
    局部变量属于方法,进栈内存。
    3)生命周期不同:
    成员变量随着对象的创建而存在,随着对象的消失而消失。
    局部变量随着方法的调用而存在,随着方法的调用完毕而消失。
    4)初始化值不同:
    成员变量有默认的初始化值,引用数据类型初始化值为null;整数初始化值为0;小数初始化值为0.0;布尔初始化值为false;字符初始化值为‘\u0000’ 。局部变量没有默认初始化值,必须先定义,再赋值,然后再能使用。
    注:局部变量名称可以和成员变量名称一致,调用时采取就近原则。

  4. 简单说明this关键字。

    在Java语言中,当创建一个对象后,Java虚拟机就会为其分配一个指向对象本身的指针,这个指针就是“this”。在我们使用this时,this一般出现在类的方法里面,当这个方法还没有调用的时候this指的是谁并不知道,但是当new一个对象出来之后,this指的就是当前这个对象,哪个对象调用这个方法,this指的就是谁(创建一个对象后,Java虚拟机就会为其分配一个指向对象本身的指针),如果再new一个对象,这个对象也有自己的this,this指的就是另外一个对象了。

  5. 说一说this关键字的用处。
    (1)通过this关键字可以明确的去访问一个类的成员变量,解决与局部变量名冲突的问题。
    (2)通过this关键字调用成员方法
    (3)在构造函数中可以使用this(参数)的形式调用其他的构造方法

    注意事项:
    (1)只能在构造方法中使用this调用其它的构造方法,不能在成员方法中使用。
    (2)在构造方法中,使用this调用构造方法的语句必须放在第一行,且只能出现一次。
    (3)不能在一个类的两个构造方法中使用this互相调用。

  6. 你刚才说只能在构造方法中使用this调用其他的构造方法,为什么?

    使用this()调用构造方法,其作用就是在JVM堆中构建出一个对象。为避免重复创建对象,同一个构造方法内只能调用一次this()。同时为了避免操作对象时对象还未构建成功,需要将this()的调用放在构造方法的第一行实现,以此来创建对象,防止异常。

  7. 说一下重载和重写的区别。

    方法重载发生在同一个类中,可以声明多个同名方法,通过参数列表(类型、个数、顺序)来区分不同方法。方法的重写发生在父子类中,子类可以通过重写父类中的非私有方法来实现特有功能,重写要求子类重写方法的参数列表、方法名必须与父类保持一致,返回值类型和抛出异常的范围不能大于父类,访问权限不能小于父类。

  8. 简单说一下Java中的权限修饰符。

    Java中有四种权限修饰符,分别是private、default、protected、public置于类的成员定义前,用来限定对象对该类成员的访问权限。其中private只能被所在类访问,default能被当前包中的类访问,protected能被同包类和子类访问,public可以在任何地方被访问。

  9. 简单说一下static关键字。

    static关键字可以用来修饰代码块表示静态代码块,修饰成员变量表示全局静态成员变量,修饰方法表示静态方法。

  10. 刚才你说static修饰的成员变量是静态变量且全局共享,为什么?

    静态是相对于动态的,动态是指Java程序在JVM上运行时,JVM会根据程序的需要动态创建对象并分配内存存储对象,对象使命结束后,会被垃圾回收器销毁,即内存分配回收由JVM统一管理;静态是指Java程序还没有运行时,JVM就会为加载的类分配空间,存储被static关键字修饰的内容,如静态成员变量。Java类加载到JVM中,JVM会把类以及类的静态成员变量存储在方法区,由于方法区是线程共享且很少发生GC的区域,所以被static关键字修饰的内容都是全局共享的,且只会在类加载时为其分配一次存储空间。

  11. 那什么时候使用static关键字呢?

    当类的某些内容不属于对象,而由对象共享即属于类的时候,就可以考虑是否用static关键字进行修饰。

  12. 简单说一下final关键字。

    final修饰类表示类无法被继承;修饰方法表示方法不能被重写;修饰的变量即为常量(即要么声明时就被初始化,要么在构造函数中初始化);修饰对象引用时引用指向的对象不能改变,对象内容可以改变。

  13. 简单说一下类的加载顺序。

    父类静态属性 → 父类静态代码块 → 子类静态属性 → 子类静态代码块 →父类普通属性 → 父类普通代码块 → 父类构造方法 → 子类普通属性 → 子类普通代码块 → 子类构造方法

  14. 详细说一下JVM中类的加载过程。

    JVM类加载机制分为五个部分:加载、验证、准备、解析、初始化。
    加载指的是把class字节码文件从各个来源(一般的加载来源包括从本地路径下编译生成的.class文件,从jar包中的.class文件,从远程网络,以及动态代理实时编译)通过类加载器装载入内存中;
    验证主要是为了保证加载进来的字节流符合虚拟机规范,不会造成安全错误;
    准备主要是为类变量分配内存,并且赋予初值(特别需要注意,初值,不是代码中具体写的初始化的值,而是Java虚拟机根据不同变量类型的默认初始值);
    解析将常量池内的符号引用替换为直接引用的过程;
    初始化这个阶段主要是对类变量初始化,是执行类构造器的过程。换句话说,只对static修饰的变量或语句进行初始化(如果初始化一个类的时候,其父类尚未初始化,则优先初始化其父类。如果同时包含多个静态变量和静态代码块,则按照自上而下的顺序依次执行)。

  15. 刚才你提到加载过程中使用类加载器,那么你对类加载器了解多少?具体有什么分类,挑一个你最熟悉的说一说?

    Java类加载器是Java运行时环境的一部分,负责动态加载Java类到Java虚拟机的内存空间中。Java类在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成java.lang.Class类的一个实例。具体可以分为,启动类加载器、扩展类加载器、应用程序类加载器以及用户自定义类加载器。

  16. 既然Java已经提供了三种类加载器,为什么还要提供自定义加载器呢?自定义加载器的意义何在?

    一方面是由于java代码很容易被反编译,如果需要对自己的代码加密的话,可以对编译后的代码进行加密,然后再通过实现自己的自定义类加载器进行解密,最后再加载。另一方面也有可能从非标准的来源加载代码,比如从网络来源,那就需要自己实现一个类加载器,从指定源进行加载。

  17. 刚才你说符号引用和直接引用,你对这两种引用类型是怎么理解的?

    符号引用,即一个字符串,但是这个字符串给出了一些能够唯一性识别一个方法、一个变量、一个类的相关信息。符号引用与虚拟机实现的布局无关,引用的目标并不一定要已经加载到内存中。各种虚拟机实现的内存布局可以各不相同,但是它们能接受的符号引用必须是一致的,因为符号引用的字面量形式明确定义在Java虚拟机规范的Class文件格式中;直接引用,直接引用可以是指向目标的指针,相对偏移量或是一个能间接定位到目标的句柄。如果有了直接引用,那引用的目标必定已经在内存中存在。(举个例子来说,现在调用方法hello(),这个方法的地址是1234567,那么hello就是符号引用,1234567就是直接引用)。在解析阶段,虚拟机会把所有的类名,方法名,字段名这些符号引用替换为具体的内存地址或偏移量,也就是直接引用。

  18. 刚才你说到类构造器(我刚才怎么说到这么多鬼东西),能具体说说吗?

    类加载的初始化阶段是执行类构造器方法的过程。方法是由编译器自动收集类中的类变量的赋值操作和静态语句块中的语句合并而成的。虚拟机会保证子方法执行之前,父类的方法已经执行完毕,如果一个类中没有对静态变量赋值也没有静态语句块,那么编译器可以不为这个类生成方法。

  19. 什么叫双亲委派?优点是什么?

    当一个类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父 类去完成,每一个层次类加载器都是如此,因此所有的加载请求都应该传送到启动类加载器中, 只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的 Class),子类加载器才会尝试自己去加载。
    采用双亲委派的一个好处是比如加载位于 rt.jar 包中的类 java.lang.Object,不管是哪个加载器加载这个类,最终都是委托给顶层的启动类加载器进行加载,这样就保证了使用不同的类加载器最终得到的都是同样一个Object对象。

  20. 抽象类和接口的区别
    (1)抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;
    (2)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
    (3)抽象类可以有静态代码块和静态方法,而接口中不能含有静态代码块以及静态方法;
    (4)一个类只能继承一个抽象类,而一个类却可以实现多个接口。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值