Java八股文

什么是面向对象

对比面向过程注重事情的步骤顺序,面向对象更关注有哪些参与者(对象),各种需要做什么,易于扩展。

封装

内部对外部来说是透明的,无需修改关心内部实现

例如:

操作数据库,不需要关心连接简历,sql执行,引入mybatis,调方法即可
JavaBean 属性私有,不能由外部随意修改。

继承

继承基类方法,并做出自己的改变、拓展
子类共性的方法或者属性直接使用父类的、拓展自己的个性

多态

对同一个方法引用会有不同效果
继承、方法重写、父类引用指向子类对象
(无法调用子类特有功能,必须父类也有)

JDK JRE JVM

JDK java开发工具,JDK包括JRE 和 Java工具
JRE 运行环境 JRE包括JVM
JVM 虚拟机 适配操作系统(一次编译,到处运行)调用类库lib解释.class文件,再映射到系统调用

==和equals

==对比栈中的值,基本数据类型是变量值,引用数据类型是堆中内存对象的地址,equals()方法用于比较对象的内容是否相等,通常被类重写以实现特定的比较逻辑。
通常equals()重写后hashcode也要重写,否则可能出现equals为true而hashcode不同的情况,正常来说equals为true则hashcode一定相同,而hashcode相同,equals不一定为true

final

修饰类:表示类不可被继承
修饰方法:方法不可被子类覆盖,但是可以重载
修饰变量:一旦赋值不可以更改值

抽象类和接口的异同点

相同:两者不能实例化,可以定义抽象方法
区别:定义的关键字不同,抽象类用的是abstract,接口用的是interface。子类拓展抽象类时用的时extend,拓展接口时用的implete。一个类只能继承一个父类,但可以实现多个接口。接口相比抽象类,少了成员属性和构造器。需要子类继承成员变量,或者需要控制子类实例化时,用抽象类,否则用接口

static

Java类中包含了成员变量、方法、构造器、初始化块和内部类(包括接口、枚举)5种成员,static关键字可以修饰除了构造器外的其他4种成员。static关键字修饰的成员被称为类成员。类成员属于整个类,不属于单个对象。 static关键字有一条非常重要的规则,即类成员不能访问实例成员,因为类成员属于类的,类成员的作用域比实例成员的作用域更大,很容易出现类成员初始化完成时,但实例成员还没被初始化,这时如果类成员访问实力成员就会引起大量错误。 static修饰的部分会和类同时被加载。被static修饰的成员先于对象存在,因此,当一个类加载完毕,即使没有创建对象也可以去访问被static修饰的部分。 静态方法中没有this关键词,因为静态方法是和类同时被加载的,而this是随着对象的创建存在的。静态比对象优先存在。也就是说,静态可以访问静态,但静态不能访问非静态而非静态可以访问静态。

请你说说String类,以及new和字符串直接量的区别

String是Java中常见的API,被final修饰,提供了很多对字符串操作的方法, - char charAt(int index):返回指定索引处的字符; - String substring(int beginIndex, int endIndex):从此字符串中截取出一部分子字符串; - String trim():删除字符串前导和后置的空格; - int indexOf(String str):返回子串在此字符串首次出现的索引; - int lastIndexOf(String str):返回子串在此字符串最后出现的索引; - boolean startsWith(String prefix):判断此字符串是否以指定的前缀开头; - boolean endsWith(String suffix):判断此字符串是否以指定的后缀结尾; - String toUpperCase():将此字符串中所有的字符大写; - String toLowerCase():将此字符串中所有的字符小写; - String replaceFirst(String regex, String replacement):用指定字符串替换第一个匹配的子串; - String replaceAll(String regex, String replacement):用指定字符串替换所有的匹配的子串。

  • new :JVM会用常量池来管理,再调用String类的构造器来创建一个新的String对象,新创建的String对象会被保存在堆内存中。
  • 字符串直接量:JVM会用常量池来管理,节省内存空间

String StringBuffer StringBuilder

  • String:不可变类型,增删效率低,复用率高
  • StringBuffer:可变类型,线程安全,更改效率高
  • StringBuilder:可变类型,线程不安全,性能比Buffer更高

hashCode和equals()

  • hashCode():获取哈希码,equals():比较两个对象是否相等。
  • 二者两个约定:如果两个对象相等,它们必须有相同的哈希码;若两个对象的哈希码相同,他们却不一定相等。也就是说,equals()比较两个对象相等时hashCode()一定相等,hashCode()相等的两个对象equqls()不一定相等。
  • 加分回答:由于hashCode()与equals()具有联动关系,equals()重写时,hashCode()进行重写,使得这两个方法始终满足相关的约定。

执行顺序

无继承:

  1. 执行顺序

    1. 静态成员变量
    2. 静态代码块
    3. 普通成员变量
    4. 普通代码块
    5. 构造函数
  2. 总结:

     1. 静态->普通
     2. 变量->代码块->构造函数
     3. 构造函数是最后执行的
    

继承
执行顺序
1. 父类的静态成员变量
2. 父类的静态代码块
3. 子类的静态成员变量
4. 子类的静态代码块
5. 父类的成员变量
6. 父类的代码块
7. 父类的构造函数
8. 子类的成员变量
9. 子类的代码块
10. 子类的构造函数

总结:

  1. 先父类再子类
  2. 如果子类有静态成员变量和静态代码块,则执行完父类的静态成员变量和静态代码块后,接着执行子类的静态变量和静态代码块,
    否则直接按照父类的变量->代码块->构造函数,再执行子类的变量->代码块->构造函数
  3. 需要注意的是子类的静态变量和静态代码块是优先于父类的普通成员变量和代码块以及构造函数的。
  4. 这也说明了先静态->再普通

posted on 2024-03-05 16:23  放水。  阅读(6)  评论(0编辑  收藏  举报

导航