
1
/ 114
1
、面向对象的特征有哪些方面?
答:面向对象的特征主要有以下几个方面:
-
抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象
两方面。抽象只关注对象有哪些属性和行为,
并不关注这些行为的细节是什
么。
-
继承:继承是从已有类得到继承信息创建新类的过程。提供继承信息的类被称为父类
(超类、基类);得到继承信息的类被称为子
类(派生类)。继承让变化中
的软件系统有
了一定的延续性,同时继承也是封装程序中可
变因素的重要手段(如果不能
理解请阅读阎
宏博士的《
Java 与模式》或《设计模式精解》中关
于桥梁模式的部分)。
-
封装:通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定
义的接口。面向对象的本质就是将现实世界描
绘成一系列完全自治、封闭的
对象。我们在
类中编写的方法就是对实现细节的一种封装;
我们编写一个类就是对数据和
数据操作的封
装。可以说,封装就是隐藏一切可隐藏的东西
,只向外界提供最简单的编程
接口(可以想
想普通洗衣机和全自动洗衣机的差别,明显全
自动洗衣机封装更好因此操作
起来更简单;
我们现在使用的智能手机也是封装得足够好的
,因为几个按键就搞定了所有
的事情)。
-
多态性:多态性是指允许不同子类型的对象对同一消息作出不同的响应。简单的说就是
用同样的对象引用调用同样的方法但是做了不
同的事情。多态性分为编译时
的多态性和运
行时的多态性。如果将对象的方法视为对象向
外界提供的服务,那么运行时
的多态性可以
解释为:当
A 系统访问
B 系统提供的服务时,
B 系统有多种提供服务的方式
,但一切对
A
系统来说都是透明的(就像电动剃须刀是
A 系统,
它的供电系统是
B 系统,
B 系统可以使
用电池供电或者用交流电,甚至还有可能是太
阳能,
A 系统只会通过
B 类对象调用供电的
方法,但并不知道供电系统的底层实现是什么
,究竟通过何种方式获得了动
力)。方法重
载(
overload)实现的是编译时的多态性(也称为前绑定),而方法重写(override)实现
的是运行时的多态性(也称为后绑定)。运行
时的多态是面向对象最精髓的
东西,要实现
多态需要做两件事:
1). 方法重写(子类继承父类并重写父类中已有的或抽象的方法);
2).
对象造型(用父类型引用引用子类型对象,这
样同样的引用调用同样的方法
就会根据子类
对象的不同而表现出不同的行为)。
2
、访问修饰符 public,private,protected,
以及不写(默认)时的区别?
答:
修饰符
当前类
同
包
子
类
其他包
public
√
√
√
√
protected
√
√
√
×
default
√
√
×
×
privat
e
√
×
×
×
类的成员不写访
问修饰时默认
为
default。
默认对于同一个
包中的其他类
相当于公开
(
public),对
于不是同
一个包中的其
他类相当于私
有(
private)。
受保护(
protected)对
子类相当于公开
,对不是同一包
中的没有
父子关系的类相
当于私有。
Java 中,外部类的修
饰符只能是
public 或默认
,类的成员(包
括内部类)的修
饰符可以是以
上四种。
3
、String
是最基本的数据类型吗?
答:不是。
Java 中的基本数据类型只有
8 个:
byte、
short、
int、
long、float、double、char、
boolean
;除了基本类型(primitive type)和枚举类型(enumeration type),剩下的都是引
用类型(
reference type)。
4
、float f=3.
4;
是否正确?
答
:不正确。
3.4 是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型
(
down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换 float f =(float)3.4;
或者写成
float f =3.4F;。
5
、short s1
= 1; s1 = s1 + 1;
有错吗?short s1 = 1; s1 += 1;有错吗?
2
/ 114
答:对于
short s1 = 1; s1 = s1 + 1;由于 1 是 int 类型,因此 s1+1 运算结果也是 int 型,需要
强制转换类型才
能赋值给
short 型。而
short s1 = 1; s1 += 1;可以正确编译,因为 s1+= 1;相当
于
s1 = (short)(s1 + 1);其中有隐含的强制类型转换。
6
、Java
有没有 goto
?
答:
goto 是
Java 中的保留
字,在目前版本
的
Java 中没有使
用。(根据
James Gosling(Java
之父)编写的《
The Java Programming Language》一书的附录中给出了一个 Java 关键字列
表,其中有
goto 和
const,
但是这两个是目
前无法使用的关
键字,因此有
些地方将其称之
为保留字,其实
保留字这个词应
该有更广
泛的意义,因为
熟悉
C 语言的程序
员都知道,在
系统类库中使用
过的有特殊意义
的单词或
单词的组合都被
视为保留字)
7
、int
和 Integer
有什么区别?
答:
Java 是一个
近乎纯洁的面向
对象编程语言
,但是为了编程
的方便还是引
入了基本数据
类型,但是为了
能够将这
些基本数据类型
当成对象操作,
Java 为每一个基本数据类型都引
入了对应的包装
类型(
wrapper class),int 的包装类就是 Integer,从 Java 5 开始引入了自
动装箱
/拆箱
机制,使得二
者可以相互转换
。
Java
为每个原始类型提供了包装类型:
-
原始类型: bo
olean
,char
,byte,short,int,long,float,double
-
包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
<span sty
le="color:
#;">class Auto
UnboxingTest
{
public stat
ic void m
ain(String[] args)
{
Integer
a = new I
nteger(3);
Integer
b = 3;
//
将 3
自动装箱成 Integer 类型
int c = 3;
Syst
em.out.print
ln(a == b); // f
alse
两个引用没有引用同一对象
Syst
em.out.print
ln(a == c); //
true a
自动拆箱成 int
类型再和 c
比较
}
}
</span>
最近还遇到一个
面试题,也是和
自动装箱
和拆箱有点关系
的,代码如下
所示:
public class Test
03 {
public stat
ic void m
ain(String[] args)
{
Integer
f1 = 100, f2 =
100, f3 = 150
, f4 = 150;
Syst
em.out.print
ln(f1 == f2);
Syst
em.out.print
ln(f3 == f4);
}
}
如果不明就里很
容易认为两个输
出要么都
是
true 要么都是
false。首先需要注意的是 f1、f2、
f3
、f4
四个变量都是 Integer 对象引用,所以下面的==运算比较的不是值而是引用。装箱的
本质是java基础笔试题 csdn什么呢?
当我们给一个
Integer 对象赋
一个
int 值的时候
,会调用
Integer 类的静态方
法
valueOf,
如果看看
valueOf 的源代码就知道发生了什么。
public stat
ic Integer v
alueOf(int i
) {
if (i >= I
ntegerCache.lo
w && i <= I
ntegerCache.hi
gh)
retur
n IntegerCache.
cache[i + (-
Integer
Cache.low)];
return new
Integer
(i);
}
3
/ 114
Integer
Cache
是 Integer
的内部类,其代码如下所示:
privat
e static class I
ntegerCache {
static fi
nal int low
= -128;
static fi
nal int high;
static fi
nal Integer
cache[];
static {
// high
value m
ay be configured by
property
int h =
127;
Stri
ng integerCache
HighProp
Value =
sun
.misc.VM.getS
avedProperty
("jav
a.lang.Integer.Int
egerCache.high"
);
if (integer
CacheHigh
PropValue !=
null) {
try
{
int i
= parseI
nt(integerCac
heHighPropVal
ue);
i
= Math.max(i
, 127);
// Ma
xim
um array size i
s Integer.MAX_
VALUE
h =
Math.mi
n(i, Int
eger.MAX_VAL
UE - (-low) -
1);
} catc
h( Num
berFormat
Exception nfe) {
// I
f the propert
y cannot be
parsed into an i
nt, ignore i
t.
}
}
high
= h;
cache
= new I
nteger[(high -
low) + 1];
int j
= low;
for(i
nt k = 0; k < cac
he.length; k
++)
cac
he[k] = new I
nteger(j++);
// rang
e [-128, 127]
must be i
nterned (JLS7 5.1.7
)
assert
IntegerCache.h
igh >= 127;
}
privat
e IntegerCache(
) {}
}
简单的说,
如果整型字面量的值在-128 到 127 之间,那么不会 new 新的 Integer 对象,而是
直接引用常量池
中的
Integer 对象,
所以上面的面试题中 f1==f2 的结果是 true,而 f3==f4
的结果是
false。
提醒:越是貌似简单的面试题其中的玄机就越多,需要面试者有相当深厚的功力。
8
、&
和
&&
的区别?
答:
&运算符
有两种用法
:
(1)按位与;
(2)逻辑与。&&运算符是短路与运算。逻辑与跟短
路与的差别是非
常巨大的,虽然
二者都要
求运算符左右两
端的布尔值都
是
true 整个表
达式
的值才是
true。
&&之所以
称为短路运算是
因为,如果
&&左边
的表达式的值
是
false,右边
的表达式会被直
接短路掉,不会
进行运算
。很多时候我们
可能都需要用
&&而不是&,例如
在验证用户登录
时判定用户名不
是
null 而且不是
空字符串
,应当写为:
username != null
&&!usernam
e.equals(""
)
,二者的顺序不能交换,更不能用&运算符,因为第一个条件如果
不成立,根本不
能进行字符串的
equals 比较,否
则会产生
NullPointerException 异常。注意:
逻辑或运算符(
|)和短路或运算符(||)的差别也是如此。
补充:如果你熟悉 JavaScript,那你可能更能感受到短路运算的强大,想成为 JavaScript
的高手就先从玩
转短路运算开始
吧。
4
/ 114
9
、解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法。
答:通常我们定
义一个基本数据
类型的变
量,一个对象的
引用,还有就
是函数调用的现
场
保存都使用内存
中的栈空间;而
通过
new 关键字和构造器
创建的对象放
在堆空间;程序
中
的字面量(
literal)如直接书写的 100、"hello"和常量都是放在静态区中。栈空间操作起来
最快但是栈很小
,通常大量的对
象都是放
在堆空间,理论
上整个内存没
有被其他进程使
用
的空间甚至硬盘
上的虚拟内存都
可以被当
成堆空间来使用
。
String str = new
String("hel
lo");
上面的语句中变
量
str 放在栈上,
用
new 创建出
来的字符串对象
放在堆上,而
"hello"这个字
面量放在静态区
。
补充:较新版本的 Java(从 Java 6 的某个更新开始)中使用了一项叫"逃逸分析"的技术,
可以将一些局部
对象放在栈上以
提升对象
的操作性能。
10
、Math.round(
11.5)
等于多少?Math.round(-11.5)等于多少?
答:
Math.round(11.5)的返回值是 12,Math.round(-11.5)的返回值是-11。四舍五入的原理是
在参数上加
0.5 然后进行
下取整。
11
、swtich
是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String 上?
答:在
Java 5 以前,
switch(expr)中,expr 只能是 byte、short、char、int。从 Java 5 开始,
Java
中引入了枚举类型,expr 也可以是 enum 类型,从 Java 7 开始,expr 还可以是字符串
(
String)
,但是长整型(
long)在目前所有的版本中都是不可以的。
12
、用最有效率的方法计算 2 乘以 8?
答:
2 << 3(左移 3 位相当于乘以 2 的 3 次方,右移 3 位相当于除以 2 的 3 次方)。
补充:我们为编写的类重写 hashCode 方法时,可能会看到如下所示的代码,其实我们不
太理解为什么要
使用这样的乘法
运算来产
生哈希码(散列
码),而且为
什么这个数是个
素
数,为什么通常
选择
31 这个数?
前两个问题的
答案你可以自己
百度一下,选
择
31 是
因为
可以用移位和减
法运算来代替乘
法,从而
得到更好的性能
。说到这里你
可能已经想到了
:
31 * num
等价于(num <
< 5) - num
,左移 5 位相当于乘以 2 的 5 次方再减去自身就相当于乘
以
31,现在的
VM 都
能自动完成这个
优化。
public class
PhoneNum
ber {
privat
e int areaCode;
privat
e String prefix;
privat
e String lineNum
ber;
@Overr
ide
public int has
hCode() {
final int
prime = 31;
int result
= 1;
result =
prime *
result + areaCode;
result =
prime *
result
+ ((
lineNumber =
= null)
?
0 : li
neNumber.hash
Code());
result =
prime *
result + ((prefix ==
null) ? 0 : prefi
x.hashCode())
;
return result
;
}
@Overr
ide
public bool
ean equals(Obj
ect obj) {
if (this =
= obj)
5
/ 114
retur
n true;
if (obj == n
ull)
retur
n false;
if (getClass(
) != obj.get
Class())
retur
n false;
PhoneNum
ber other
= (PhoneNum
ber) obj;
if (areaC
ode != other.ar
eaCode)
retur
n false;
if (lineNum
ber == nul
l) {
if (other.l
ineNum
ber != null)
retur
n false;
} else if (!
lineNumber.e
quals(other
.lineNumber))
retur
n false;
if (prefix =
= null) {
if (other.
prefix != nul
l)
retur
n false;
} else if (!
prefix.equal
s(other.prefix))
retur
n false;
return true;
}
}
13
、数组有没有 length()方法?String 有没有 length()方法?
答:数组没有
length()方法
,有
length 的属
性。
String 有 length()方法。JavaScript 中,获得
字符串的长度是
通过
length 属性得到的
,这一点容
易和
Java 混淆。
14
、在 Java
中,如何跳出当前的多重嵌套循环?
答:在最外层循
环前加一个标记
(Label)如 A,然后用 break A;可以跳出多重循环。(Java
中支持带标签
的
break 和
continue 语句,作用有点类似于 C 和 C++中的 goto 语句,但是就
像要避免使用
goto 一样,应该避
免使用带标签
的
break 和
continue,因为它
不会让你的程
序变得更优雅,
很多时候甚至有
相反的作
用,所以这种语
法其实不知道
更好)
15
、构造器(co
nstructor
)是否可被重写(override)?
答:构造器不能
被继承,因此不
能被重写
,但可以被重载
。
16
、两个对象值相同(x.equals(y) == true),但却可有不同的 hash code,这句话对不对?
答:不对,如果
两个对象
x 和
y 满足
x.equals(y) == true,它们的哈希码(hash code)应当
相同。
Java 对于 eqauls 方法和 hashCode 方法是这样规定的:(1)如果两个对象相同(equals
方法返回
true),
那么它们的
hashCode 值
一定要相同;
(2)如果两个对象的 hashCode 相同,
它们并不一定相
同。当然,你未
必要按照
要求去做,但是
如果你违背了
上述原则就会发
现
在使用容器时,
相同的对象可以
出现在
Set 集合中,同时增加
新元素的
效率会大大下降
(对于使用哈希
存储的系统,如
果哈希码
频繁的冲突将会
造成存取性能
急剧下降)。
补充:关于 equals
和 hashCode
方法,很多 Java 程序都知道,但很多人也就是仅仅知道
而已,在
Joshua Bloch
的大作《
Effective Java》(很多软件公司,《Effective Java》、
《
Java 编程思想
》以及《重构:
改善既有代码
质量》是
Java 程序员必看书
籍,如果你还
没
看过,那就赶紧
去亚马逊买一本
吧)中是
这样介绍
equals 方法的:首
先
equals 方法必
须满
足自反性(
x.equals(x)必须返回 true)、对称性(x.equals(y)返回 true 时,y.equals(x)也必须
返回
true)、
传递性(
x.equals(y)和 y.equals(z)都返回 true 时,x.equals(z)也必须返回 true)
和一致性(当
x 和
y 引用的对象
信息没有被修
改时,多次调
用
x.equals(y)应该得到同样的
返回值),而且
对于任何非
null 值的引用
x,
x.equals(null)必须返回 false。
实现高质量的
equals方法的诀窍包括:1. 使用==操作符检查"参数是否为这个对象的引用";
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/6860.html