基础语法、关键字、面向对象
目录
基础语法 #
long 类型的数据一定要在数值后面加上 L,否则将作为整型解析。 #
switch 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String 上? #
Java5 以前 switch(expr)中,expr 只能是 byte、short、char、int。
从 Java 5 开始,Java 中引入了枚举类型, expr 也可以是 enum 类型。
从 Java 7 开始,expr还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的。
访问修饰符public、private、protected、以及不写(默认)时的区别? #
private
和protected
无法用来修饰类。
关键字 #
final、finally、finalize的区别? #
final 用于修饰变量、方法和类。
- final 变量:被修饰的变量不可变,不可变分为
引用不可变
和对象不可变
,final 指的是引用不可变
,final 修饰的变量必须初始化,通常称被修饰的变量为常量
。 - final 方法:
被修饰的方法不允许任何子类重写
,子类可以使用该方法。 - final 类:被修饰的类不能被继承,所有方法不能被重写。
finally 作为异常处理的一部分,它只能在 try/catch
语句中,并且附带一个语句块表示这段语句最终一定被执行(无论是否抛出异常),经常被用在需要释放资源的情况下,System.exit (0)
可以阻断 finally 执行。
finalize 是在 java.lang.Object
里定义的方法,也就是说每一个对象都有这么个方法,这个方法在 gc
启动,该对象被回收的时候被调用
。
一个对象的 finalize 方法只会被调用一次,finalize 被调用不一定会立即回收该对象,所以有可能调用 finalize 后,该对象又不需要被回收了,然后到了真正要被回收的时候,因为前面调用过一次,所以不会再次调用 finalize 了,进而产生问题,因此不推荐使用 finalize 方法。
为什么要用static关键字? #
通常来说,用new创建类的对象时,数据存储空间才被分配,方法才供外界调用。但有时我们只想为特定域分配单一存储空间,不考虑要创建多少对象或者说根本就不创建任何对象,再就是我们想在没有创建对象的情况下也想调用方法。在这两种情况下,static关键字,满足了我们的需求。
static
方法无法被重写static
方法可以访问static
变量,因为都是类初始化时加载。static
方法不可以访问非static
方法- 代码块执行顺序静态代码块——> 构造代码块 ——> 构造函数——> 普通代码块 继承中代码块执行顺序:父类静态块——>子类静态块——>父类代码块——>父类构造器——>子类代码块——>子类构造器
面向对象 #
- 封装。封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
- 继承。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。
- 多态性。它是指在父类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为,这使得同一个属性或方法在父类及其各个子类中具有不同的含义。
Java语言是如何实现多态的? #
本质上多态分两种:
- 编译时多态(又称静态多态)
- 运行时多态(又称动态多态)
重载(overload)就是编译时多态的一个例子,编译时多态在编译时就已经确定,运行的时候调用的是确定的方法。我们通常所说的多态指的都是运行时多态,也就是编译时不确定究竟调用哪个具体方法,一直延迟到运行时才能确定。 这也是为什么有时候多态方法又被称为延迟方法的原因。
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。
构造器不能被继承,因此不能被重写,但可以被重载。每一个类必须有自己的构造函数,负责构造自己这部分的构造。子类不会覆盖父类的构造函数,相反必须一开始调用父类的构造函数。
抽象类和接口的区别是什么? #
语法层面上的区别:
- 抽象类可以提供成员方法的实现细节,而接口中只能存在
public abstract 方法
; - 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是
public static final类型的
; - 接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
- 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
设计层面上的区别:
- 抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。
- 设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。
想要深入了解,可以参考这篇文章 :https://www.cnblogs.com/dolphin0520/p/3811437.html
java 创建对象有哪几种方式? #
java中提供了以下四种创建对象的方式:
- new创建新对象
- 通过反射机制
- 采用clone机制
- 通过序列化机制
前两者都需要显式地调用构造方法。对于clone机制,需要注意浅拷贝和深拷贝的区别,对于序列化机制需要明确其实现原理,在java中序列化可以通过实现Externalizable或者Serializable来实现。
package demo1;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
public class Main1 {
public static void main(String[] args) throws IllegalAccessException, InstantiationException,
InvocationTargetException, CloneNotSupportedException, IOException, ClassNotFoundException {
//第一种
Demo demo=new Demo();
System.out.println(demo);
//第二种
Class<Demo> demoClass=Demo.class;
System.out.println(demoClass.newInstance());
System.out.println(demoClass.getConstructors()[0].newInstance());
//第三种
Demo demoClone=(Demo)demo.clone();
System.out.println(demoClone);
//第四种
ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream("demo.ser"));
objectOutputStream.writeObject(demo);
objectOutputStream.close();
ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream("demo.ser"));
Demo demoSer=(Demo)objectInputStream.readObject();
System.out.println(demoSer);
}
}
class Demo implements Cloneable, Serializable {
public Demo(){
System.out.println("Demo类被创建啦");
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
什么是不可变对象?好处是什么? #
不可变对象指对象一旦被创建,状态就不能再改变,任何修改都会创建一个新的对象,如 String、Integer及其它包装类.不可变对象最大的好处是线程安全.
能否创建一个包含可变对象的不可变对象?
当然可以,比如final Person[] persons = new Persion[]{}
。 persons
是不可变对象的引用,但其数组中的Person实例却是可变的.这种情况下需要特别谨慎,不要共享可变对象的引用.这种情况下,如果数据需要变化时,就返回原对象的一个拷贝.