什么是面向对象?对面向对象的理解?
洗衣服
面向过程:
人->打开洗衣机->放衣服->放洗衣粉->清洗->烘干
面向对象:
人的方法:打开洗衣机、放衣服、放洗衣粉
洗衣机的方法:清洗、烘干
特点:面向过程更高效,面向对象更易于复用、扩展和维护
面向对象的三大特性
封装
明确表示出外部可以使用的方法和属性,外部调用不需要再关心内部是如何实现的,调用即可。
外部传入的数据可以进行修饰后再给内部使用
继承
继承基类的方法,然后作出自己的改变或扩展,父类中有用的方法直接用,没有的方法可以自己写。
多态
多态必须要有继承,方法重写,父类引用指向子类对象
JDK、JRE、JVM区别和联系
JDK:Java Development Kit java开发工具
JRE:Java Runtime Environment java运行时环境
JVM:Java Virtual Machine java虚拟机
JRE包含 JVM和lib(类库)
JDK包含 JRE和Java工具
==和equals
==是对比栈中的值,Object中的equals其实也是用==去判断相等的,如果要判断内容是否相等,需要重写。
final
修饰类:表示类不可以被继承
修饰方法:表示方法不可以被子类覆盖(重写)但是可以重载
修饰变量:变量一旦被赋值就不可以再更改他的值了
修饰类变量:只能在声明时指定初始值或者在静态代码块中指定初始值
修饰成员变量:只能在声明时指定初始值或者在普通代码块中初始值或者构造器中初始
修饰局部变量:系统不会给局部变量初始化,必须显示的对变量进行赋值,如果不赋值在调用变量时就会报错
为什么局部内部类和匿名内部类只能访问局部final变量
首先内部类并不会因为定义在方法中就会随着方法的执行完毕就被销毁。
内部类在编译后也是生成两个class文件,所以内部类和外部类是同一级别的,不会随之方法执行完毕就销毁。
具体原因:
当外部类的方法结束时,局部变量就会被销毁了,但是内部类对象可能还存在(只有没有人再引用他时,才会死亡)。这里就出现了一个矛盾:内部类对象访问了一个不存在的变量,为了解决这个问腿,就将局部变量复制一份作为内部类的成员变量,这样当局部变量死亡后,内部类仍然可以访问他,实际访问的是局部变量的“copy“,这样就好像延长了局部变量的生命周期。
将局部变量复制为内部类的成员变量时,必须保证这两个变量是一样的,也就是如果我们在内部类中修改了成员变量,方法中的局部变量也就跟着改变了,出问题了。
就将局部变量设置为final,对他初始化后,我就不让你再去修改这个变量,就保证了内部类的成员变量和方法的局部变量的一致性。这实际上也就是一种妥协,使得局部变量与内部类内建立的拷贝保持一致
String、StringBuilder和StringBuffer的区别
String是final修饰的,不可改变,每次修改都会创建一个新的String。
StringBuilder是可变的,
StringBuffer也是可变的,因为StringBuffer又synchronized修饰,所以StringBuffer是线程安全的。
使用场景:
如果字符串要经常修改,就要使用StringBuilder和StringBuffer,如果要在多线程下作为共享变量使用,就必须使用StringBuffer。
重载和重写的区别
重载:在同一个类中,方法的参数不同,个数不同,类型不同,顺序不同方法就可以重载,返回值不同或者访问修饰符不同不能重载,会直接报错。
重写:发生在父子类中,方法名,参数必须一致,返回值的范围和抛出的异常范围可以小于父类,访问修饰符大于父类
接口和抽象类的区别
抽象类可以存在普通成员函数,接口中只能存在public abstract方法。
抽象类只能继承一个,接口可以实现多个(单继承,多实现)
抽象中的数据类型可以是任意的,接口中只能是public static final类型
接口设计的目的是约束,抽象类是模版。接口是like,抽象类是is
List和Set的区别
list有序可重复,按对象的进入顺序存放的,可以存放多个null,可以使用迭代器遍历也可以get(int index)按下表获取元素
set无序不可重复,只能存放一个null,只能使用迭代器遍历
ArrayList和LinkedList的区别
ArrayList是基于动态数组实现的,扩容机制:生成一个新的数组,将旧数组中的值拷贝到新数组中,但是如果不是尾部插入数据会涉及到数据的移动,性能会很低,所以使用尾插法可以极大提高性能。
LinkedList是基于链表的,插入删除操作会很快,但是遍历很麻烦,需要使用迭代器才可以,要逐一元素遍历,另外也会创建很多node,消耗较多,降低性能
HashMap和HashTable有什么区别?
HashMap方法没有synchronized修饰,线程不安全,HashTable是线程安全的。
HashMap允许key和value为null,HashTable不能为null。
底层实现:数组+链表
当链表长度超过8,数组长度小于64。链表就会转成红黑树,小于8就会又转回链表。
计算key的Hash值,对Hash值模数组长度,然后判断是否Hash冲突,如果冲突了,就调用equals判断是否相同,不相同就放入链表中。
什么是字节码?采用字节码的好处是什么?
java源代码->编译器->字节码(.class)->jvm->解释器->系统可执行的二进制文件->程序运行
字节码只需要面向虚拟机,不需要直接面对操作系统,所以可以跨平台。
Java是编译和解释并存的语言,比传统解释型语言执行效率高,又保留了解释型语言可移植的特点。解释性语言在程序运行时才解释,运行一次就解释一次。