1 、是否可以从一个 static 方法内部发出对非 static 方法的调用?
- 不可以。因为非
static
方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而static
方法调用时不需要创建对象,可以直接调用。也就是说,当一个static
方法被调用时,可能还没有创建任何实例对象,如果从一个static
方法中发出对非 static 方法的调用,那个非static
方法是关联到哪个对象上的呢?这个逻辑无法成立,所以,一个static
方法内部不能发出对非static
方法的调用。
2 、Integer 与 与 int 的区别
int
是 java 提供的 8 种原始数据类型之一。Java 为每个原始类型提供了封装类,Integer
是 java为int
提供的封装类。int
的默认值为 0,而Integer
的默认值为null
,即Integer
可以区分出未赋值和值为 0 的区别,int
则无法表达出未赋值的情况,例如,要想表达出没有参加考试和考试成绩为 0 的区别,则只能使用Integer
。Integer
提供了多个与整数相关的操作方法,例如,将一个字符串转换成整数,Integer
中还定义了表示整数的最大值和最小值的常量。
3 、Math.round(11.5) 等於多少? Math.round(-11.5) 等於多少?
Math
类中提供了三个与取整有关的方法:ceil、floor、round
,这些方法的作用与它们的英文名称的含义相对应,例如,-
ceil
的英文意义是天花板,该方法就表示向上取整,Math.ceil(11.3)
的结果为12
,Math.ceil(-11.3)
的结果是-11
;
-
floor
的英文意义是地板,该方法就表示向下取整,Math.ceil(11.6)
的结果为11,Math.ceil(-11.6)
的结果是-12;
-
round
方法,
它表示“四舍五入”,算法为Math.floor(x+0.5)
,即将原来的数字加上0.5后再向下取整,所以,Math.round(11.5)
的结果为 12,Math.round(-11.5)
的结果为-11。
4 、作用域 public,private,protected,以及不写时的区别
这四个作用域的可见范围如下图所示。
说明:如果在修饰的元素上面没有写任何访问修饰符,则表示 friendly(默认)。
5 、构造器 Constructor 是否可被 override?
- 构造器 Constructor 不能被继承,因此不能重写 Override,但可以被重载 Overload。
6 、写 clone() 方法时,通常都有一行代码,是什么?
- clone 有缺省行为,
super.clone();
因为首先要把父类中的成员复制到位,然后才是复制自己的成员。
7 、面向对象的特征有哪些方面。
- 封装、继承、抽象、多态。
- 封装。封装是保证软件部件具有优良的模块性的基础,封装的目的是实现软件部件的==“高内聚,低耦合”==,防止程序相互依赖带来变动影响。在面向对象的编程语言中,对象是封装的最基本单位。
- 继承。继承是子类自动共享父类数据和方法的机制,是类之间的一种关系,提高了软件的可重用性和可扩展性。
- 抽象。抽象就是找出一些事物的相似性和共性,然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处。
- 多态。多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在程序运行期间才能决定。多态性增强了软件的灵活性和扩展性。
8、java 中实现多态的机制是什么?
- 靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。
9、String 是最基本的数据类型吗?
- 基本数据类型(8种)包括
byte、int、char、long、float、double、boolean 和 short
。 java.lang.String
类是final
类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer
类。
10 、String s = “Hello”;s = s + " world!"; 这两行代码执行后,原始的 String 对象中的内容 到底变 了没有?
- 没有。因为
String
被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。在这段代码中,s 原先指向一个String
对象,内容是"Hello"
,然后我们对s
进行了+
操作,那么s
所指向的那个对象是否发生了改变呢?答案是没有。这时,s
不指向原来那个对象了,而指向了另一个String
对象,内容为"Hello world!"
,原来那个对象还存在于内存之中,只是s
这个引用变量不再指向它了。 - 通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用
String
来代表字符串的话会引起很大的内存开销。因为String
对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String
对象来表示。这时,应该考虑使用StringBuffer
类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。 - 至于为什么要把
String
类设计成不可变类,是它的用途决定的。其实不只String
,很多Java
标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以 Java 标准类库还提供了一个可变版本,即StringBuffer
。