1, 面向对象编程的四大特性及其含义?
答:
- 继承 : 子类对父类的扩展, 实现代码的复用, 增强了系统的可扩展性. 同时继承也实现了多态, 但是继承是侵入性的, 破坏了封装, 而且修改父类的行为会导致所有的子类都发生改变, 因此我们要慎用继承, 应该优先考虑使用组合.
- 封装 : 在面向对象的思想中, 类就是封装体, 通过把不同的逻辑和事物封装到一个模块中, 然后再把这些松散的模块组合起来构成一个系统, 从而实现高内聚,低耦合.
- 抽象 : 抽象包括行为抽象和数据抽象, 在面向对象的语言中, 类 就是对现实世界中的事物的抽象, 用类创建出对象, 用对象和对象之间的关系来模拟现实世界中各种事物之间的关系. 其中 接口 是对行为的抽象, 抽象类是对 共性 的抽象, 我们用抽象来定义系统设计的规范, 让系统的扩展都去尽可能的满足这种规范, 这可以给系统带来更好的维护性.
- 多态 : 多态主要表现在 父类或者基类的引用可以持有不同子类的实例对象, 当调用父类的方法时, 会表现出不一样的行为, 这便是多态的主要表现.
2, String、StringBuffer和StringBuilder的区别?
答: String 是 java中的字符串, 从源码中我们可以发现它内部的成员变量大部分都是 private static final 的, 而且它位于常量池当中, 由此我们可以知道 string 对象一但创建后是不可变的, 而且 string 对象之间是可以进行字面值共享的, 而 stringBuffer 和 stringBuilder 都是可变的字符串, 通过 new 关键字来获取它们的对象, 由此可知位于堆区, 他们之间的区别是 stringBuilder 不是线程安全的.
3, String a=" "和String a=new String(" ")的的关系和异同?
答: 第一种方式是在常量池当中创建了一个字面常量, 然后让栈区的引用指向这个常量, 由于常量池当中的字面值存在共用的特性, 这也是为什么我们用 == (默认比较引用)号来比较两个一样的字符串会得到 true 的原因, 而第二种方式是在堆区创建了一个新的变量, 然后让栈区的引用指向这个变量, 这和第一种方式截然不同.
4, Object 的 equals 和 == 的区别?
答: 默认没有重写equals 方法的情况下, 它们都是对两个对象引用的比较, 当然, 我们可以通过重写 equals 方法来改变比较行为, 但是 == 运算符是比较引用的行为是无法更改的.
5, 装箱, 拆箱什么含义?
答: 我们知道, java中类类型从大类可以分为两大类, 基本类型和引用类型, 基本类型是指 java 中的 八大 基本数据类型, 它们有个共同的特点, 就是存储其字面值. 和基本类型不同的是引用类型, 如通过引用类型来引用一个对象, 这便是引用类型. 装箱和拆箱便是 java 中基本数据类型和引用类型相互转换的一个过程, 如 int --> Integer, 最常见的便是集合元素, 因为集合不支持基本类型元素.
6, 遇见过哪些运行时异常? 异常处理机制有哪些?
答: 常见的运行时异常有: 空指针异常, 数组越界异常, 非法参数异常等等, 异常处理机制在 java 中主要分为两种, 一种是通过 try catch 语句来捕获并处理异常, 还有一种就是通过 throws 关键字抛出异常让调用者进行处理.
7, java的反射机制
答: java的反射机制是指在程序运行期间, 通过获取一个类的 class 对象, 然后对这个类进行解刨, 所谓解刨便是我们可以获取到这个类的所有信息, 比如私有成员变量, 和方法, 然后调用这些方法. 反射可以给编程带来很大的灵活性, 但是也有较大的缺陷, 比如不安全, 和效率问题, 大量的使用反射会使程序效率低下.
8, 什么是内部类?有什么作用?静态内部类和非静态内部类的区别?
答: 内部类是指在一个类定义的内部, 再声明一个新的类, 常见的内部类有
- 局部内部类.
- 匿名内部类.
- 成员内部类.
- 静态内部类.
内部的作用有:
- 可以用 private 和 protected 来修饰内部类, 其他类则不可以, 从而可以实现很好的隐藏效果.
- 解决实现某一个接口时的方法名冲突, 不修改接口, 采用内部类实现.
- 配合委托模式使用可以实现多重继承.
静态内部类不会持有外围内的引用, 而非静态内部类会, 这也是时常导致内存泄露的原因, 如一些局部的 匿名内部类 .
9, final、finally、finalize()分别表示什么含义?
答: final 是修饰符, 用来修饰变量, 方法, 类 , 分别表示不同的意思. finally 是 try finally 中的 代码块, 无论如何, finally 中的代码总会被得以执行. 而 finalize 是可以用来关闭外部资源, 但是这个方法并不推荐使用, 这是 java 为了使 c/c++ 程序员能够更容易接受而做的妥协, 凡是 finalize 能做的, finally 都能做的更好, 因此我们完全可忘掉这个方法.
10, 为什么匿名内部类中使用局部变量要用final修饰?
答: 用一句话来说明就是因为 变量 生命周期的不一致性. 详细解释下:
我们知道, 方法的调用会在 java 虚拟机栈中形成一个栈贞, 而栈是线程私有的内存空间, 再来说说这个方法内的局部变量, 如果我们在一个会被一个线程所调用的匿名内部类中引用了这个局部变量, 那么当这个方法调用完成后, 这个局部变量就不存在了, 但是线程还得继续运行, 那么肯定的把值进行一次拷贝, 那么拷贝过来为什么要限定成 final 呢? 如果不是 final, 那么就可以修改这个变量, 但是我们刚刚说了这个变量是位于方法所形成的栈贞中的, 不能进行线程共享, 所以会导致修改不同步问题, 所以必须定义成 final 让其不允许修改.
而如果引用的是成员变量, 就无需定义成 final , 因为不存在变量生命周期不一致性的问题, 匿名内部类任何时刻都可以通过外围内的实例对象来访问其成员变量,