修饰符用来定义类、方法或者变量,通常放在语句的最前端。
java中的修饰符主要分两类:访问修饰符和非访问修饰符
【面试题1】访问修饰符public,private,protected,以及不写(默认)时的区别?
首先注意,以上都是访问修饰符。
访问修饰符用来保护对类、变量、方法和构造方法的访问。
java提供了四种不同的访问修饰符
默认的,也称为 default,在同一包内可见,不使用任何修饰符。
私有的,以 private 修饰符指定,在同一类内可见。
共有的,以 public 修饰符指定,对所有类可见。
受保护的,以 protected修饰符指定,对同一包内的类和所有子类可见。
【面试题2】阐述静态变量和实例变量的区别。
static 关键字是java中的一个非访问修饰符,用于声明静态变量和静态方法。
静态变量是被static修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝;
实例变量必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。
静态变量在所属类被JVM连接时就会被初始化,而实例变量要创建类的实例后初始化。
【面试题3】是否可以在一个静态方法中调用非静态方法?
被static关键字修饰的变量和方法,可以不创建对象而直接通过类名访问。
我们可以从初始化时机来看这个问题,静态方法和静态变量都是在jvm连接类时初始化完成的,可以说静态方法初始化在编译时完成,而非静态方法要在运行时完成,编译时程序还没有运行,非静态方法还没有被初始化,所以不能调用。
延伸题:Java中是否可以覆盖(override)一个private或者是static的方法?
static方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而static方法是编译时静态绑定的。static方法跟类的任何实例都不相关,所以概念上不适用。
【面试题4】 抽象方法是否可同时被synchronized修饰?
java中被abstract修饰符修饰的方法是抽象方法,抽象方法没有具体实现,表明可以被子类重写。
synchronized和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。
【面试题5】java 中的final关键字有哪些用法?
1.修饰类
当用final修饰一个类时,表明这个类不能被继承。
2.修饰方法
方法前面加上final关键字,代表这个方法不可以被子类的方法重写。
3.修饰变量
表示变量只能一次赋值以后值不能被修改(常量)。
4.在内部类中使用
在方法内部类中,访问局部变量必须用final修饰!成员内部类没有问题
延伸题:下面代码的执行结果?
这段代码可以顺利编译通过并且有输出结果,输出结果为1。这说明引用变量被final修饰之后,虽然不能再指向其他对象,但是它指向的对象的内容是可变的。
【面试题6】volatile关键字是否能保证线程安全?
答案:不能
解析:volatile关键字用在多线程同步中,可保证读取的可见性,JVM只是保证从主内存加载到线程工作内存的值是最新的读取值,而非cache中。但多个线程对
volatile的写操作,无法保证线程安全。例如假如线程1,线程2 在进行read,load 操作中,发现主内存中count的值都是5,那么都会加载这个最新的值,在线程1堆count进行修改之后,会write到主内存中,主内存中的count变量就会变为6;线程2由于已经进行read,load操作,在进行运算之后,也会更新主内存count的变量值为6;导致两个线程及时用volatile关键字修改之后,还是会存在并发的情况。
volatile的写操作,无法保证线程安全。例如加入线程1,线程2,在read,load操作中,发现主内存中count的值都是5