看着这些java面试题让面试官唱征服(二)
1.使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变
使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。
例如:对于如下语句
final StringBuffer a = new StringBuffer (“immutable”);
执行如下语句将报告编译期错误
- a=new StringBuffer("");
但是执行如下语句则可以通过编译
- a.append(“broken!”);
有人在定义方法的参数时,可能想采用如下形式来阻止方法内部修改传进来的参数对象:
- public void method (final StringBuffer param){ }
实际上,这是不可能的,在该方法内部仍然可以增加如下代码来修改参数对象
- param.append(“a”);
2."==" 和equals究竟有什么区别
我们先把他们单独拎出来说
关于“==”:==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等。只能用 这一操作符。
如果一个变量指向的数据是对象类型的,那么这时候设计了两块内存,对象本身占用一块内存(堆内存)变量也占用一块内存,例如Object obj = new Object();变量obj是一个内存,new Object是另一个内存。此时,变量obj所对应的内存中存储的数值就是对象占用的那块内存的首地址。对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就要用双等操作符进行比较。
关于equals:equals方法就是比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。。
例如:对于下面两个代码:
- String a = new String(“foo”);
- String b = new String(“foo”);
a、b两个变量分别指向了两个不同的对象,它们的首地址是不同的,即a和b 中所存储的数值是不同的。所以a==b将返回false,而这两个对象的内容是相同的,所以表达式a.equals(b)将返回true
- 注意的是,字符串的比较基本上都是用equals方法
- 如果一个类没有自己定义equals方法,它默认的equals方法(从Object类继承的)就是使用==操作符,也就是比较两个变量指向的对象是否是同一对象,这时候无论是equals还是双等都会得到同样的结果,如果比较的是两个独立的对象则总返回false。如果你编写的类希望能够比较该类创建的两个实例对象内容是相同的,那么你必须覆盖equals方法。
3.静态变量和实例变量的区别
在语法定义上的区别:
- 静态变量前要加static关键字,而实例变量前则不加。
在程序运行时的区别:
- 实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称之为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间。静态变量就可以被使用 了。
总之 :实例变量必须创建对象后才能通过这个对象来使用,静态变量则可以直接使用类名来引用,
示例:
public class VariantTest{
public static int staticVar = 0;
int instanceVar = 0;
public VariantTest(){
staticVar++;
instanceVar++;
System.out.println("staticVar="+staticVar + ",instanceVar="+instanceVar);
}
}
在上面的程序中,无论创建多少个实例对象,永远都只分配了一个staticVar变量,并且每创建一个实例对象,这个staticVar就会加1;但是每创建一个实例对象,就会分配一个instanceVar,即可能分配多一个instanceVar,并且每个instanceVar的值都只会自加了一次。
4.是否可以从一个static方法内部发出对非static方法的调用
不可以
因为非static方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而static方法调用时不需要创建对象,可以直接调用。也就是说,当一个static方法被调用时可能还没有创建任何实例对象,如果从一个static方法内部发出对非static方法的调用,那个非static方法是关联到对象上的呢?这个逻辑是无法成立的。
5.Integer与int的区别
int:
是java提供的八种原始数据类型之一。java为每个原始类型提供了封装类。
Integer:
是java为int提供的封装类,int的默认值为0,而integer的默认值为null,即Integer可以区分出未赋值和值为0的区别,int则无法表达出未赋值的情况,
例如:
要想表达出没有参加考试和考试成绩为0的区别,则只能使用Integer。在JSP开发中,Integer的默认值为null,所以用el表达式在文本框中显示时,值为空白字符串,而int默认的默认值为0,所以用el表达式在文本框中显示时,结果为0,所以int不适合作为web层的表单数据的类型
6.Math.round(11.5)等于多少?Math.round(-11.5)等于多少?
Math中提供了三个与取整有关的方法:ceil、floor、round,这些方法的作用与他们的英文名称的含义相对应。
例如
ceil:意味天花板,所以是向上取整Math.ceiil(11.3)为12,Math.ceil(-11.3)为-11
floor:意味地板,所以是向下取整,Math.floor(11.3)为11,Math.floor(-11.3)为-12
round:表示四舍五入,算法为Math.floor(x+0.5),即将原来的数字加上0.5再向下取整,所以Math.round(11.5)为12,Math.tound(-11.5)为-11
7.请说出作用域public,private,protected,以及不写时的区别
作用域 | 当前类 | 同包 | 子孙类 | 其他包 |
---|---|---|---|---|
public | √ | √ | √ | √ |
private | √ | x | x | x |
protected | √ | √ | √ | x |
friendly | √ | √ | x | x |
8.重载(overload)和重写(override)的区别。重载的方法是否可以改变返回值的类型?
重载:
表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同)
重写:
表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种变现。子类覆盖父类的方法时,只能比父类抛出更少的异常,或者是抛出父类抛出的异常的子异常,因为子类可以解决父类的一些问题,不能比父类有更多的问题。子类方法的访问权限只能比父类的更大,不能更小。
那么overload可以改变返回值的类型吗?
- 如果两个方法的参数列表完全一样,不可以让他们的返回值不同来实现重载
- 但如果几个重载的方法的参数列表完全一样,他们的返回者类型当然也可以不一样。
9.构造器Constructor是否可被override?
构造器Constructor不能被继承,因此不能重写override,但可以被重载overload。
10.接口是否可以继承接口?抽象类是否可以实现接口?抽象类是否可继承具体类?抽象类中是否可以有静态的main方法?
- 接口可以继承接口。抽象类可以实现接口。
- 抽象类可以继承实体类,但前提是实体类必须有明确的构造函数
- 抽象类可以有静态的main方法
- 最后要记得,抽象类与普通类唯一的区别就是不能创建实例对象和允许有abstract方法
11.写clone()方法时,通常都有一行代码是什么?
- clone有缺省行为,super.clone();因为首先要把父类中的成员复制到位,然后才是复制自己的成员。
本文地址:https://blog.csdn.net/weixin_42507474/article/details/107678569
上一篇: 反射和反序列化破坏单例及解决方案