1、面向对象的特征有哪些?
继承:通过继承允许复用已有的类,子类可以从父类哪里继承得到的方法和成员变量,而且子类可以修改或增加新的方法使之适合子类的需要。
封装:把对对象的状态数据隐藏起来,再通过合适的方法来允许尾部程序修改对象的状态数据。Java的封装主要通过private、protected、public等访问控制符来实现。
多态性:当同一个类型的引用类型的变量在执行相同的方法时,实际上会呈现出不同的行为特征。比如程序有Animal a1 = new Animal() ; Animal a2 = new Wolf();虽然a1、a2两个引用变量的类型都是Animal,但当他们调用一个run()方法时,如果Wolf重写类run()方法,这就导致a1、a2两个变量执行run()方法时呈现出不同的行为特征,这就是多态。(父类引用指向子类对象)
2、Java中实现多态的机制是什么?
Java允许父类或接口定义的引用变量指向子类或具体实现类的实例对象(父类引用指向子类对象),而程序调用的方法在运行时才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存中正在运行的那个对象的方法,而不是引用变量的类型中定义的方法,
4、String是基本数据类型吗?
基本数据类型:byte boolean short char int float long double ;
String 是引用类型。
而且 java.lang ,String 类是final类型,因此不可以继承这个类。
7、String 和StringBuffer、StringBuilder的区别
Java提供了:String、StringBuffer和StringBuilder,它们都是CharSequence的实现类,都可以作为字符串使用。
String :代表字符序列不可变的字符串;
StringBuffer和StringBuilder : 字符序列可变的字符串。
StringBuffer 和StringBuilder的区别:
StringBuffer:线程安全,性能略低;
StringBuilder:线程不安全,使用于单线程,性能较高。
8、Collection 和 Collections 的区别:
collection :是集合类(List Set Queue的跟接口);
Collections:是针对集合类的一个工具类,他提供一系列的静态方 法实现对各种集合的搜索、排序。线程安全化等操作。
9、说说&和&&的区别。
&和&&都可以用作逻辑与的运算符,当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。
区别:&&具有短路的功能,如果第一个表达式为false,就不再计算第二个表达式,因此&&之后的表达式根本不会执行;表达式,例如,对于if(a >8 && b > 5),当a小于等于8时,由于&&之前的表达式已经
再例如if(str != null && !str.equals(""))表达式,当str为null时,后面的表达式不会执行,因此不会出现NullPointerException如果将&&改为&,则会抛出NullPointerException异常。
再例如if(x > 8 & ++y)与if(x > 8 && ++y ),当a小于等于8时,前一个表达式中y的值会增长;后一个表达式中y的值不会增加。
除此之外,&还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位,例如,0x31 & 0x0f的结果为0x01。
10、Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?
Overload是方法的重载
Override是方法的重写,也叫覆盖。
Overload要求两个方法具有方法名相同、形参列表不同的要求,返回值类型不能作为重载的条件。
Override要求子类方法与父类方法具有“两同两小一大”的要求。两同指:即父类方法、子类方法的方法名相同、形参列表相同;两小指:子类方法返回值类型要么是父类方法返回值类型的子类、要么与父类方法返回值类型相同;子类方法声明抛出的异常类型要么是父类方法声明抛出的异常类型的子类、要么与父类声明抛出的异常类型相同;一大指:子类方法的访问权限要么与父类方法的访问权限相同,要么比父类方法的访问权限更大。
Overloaded的方法是可以改变返回值的类型。
11、Java如何跳出当前的多重嵌套循环?
在Java中,要想跳出多重循环,可以在外面的循环语句前定义一个标号,然后在里层循环体的代码中使用带有标号的break 语句,即可跳出外层循环。例如,
没有使用标号的break语句,是跳出内层循环:
13、String s = new String("xyz");创建了几个String Object?
两个。一个是直接量的xyz对象;另一个是通过new Sting()构造器创建出来的String对象。
通常来说,应该尽量使用直接量的String对象,这样具有更好的性能。
15、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
对于short s1 = 1; s1 = s1 + 1; 由于s1+1运算时会的类自动提升表达式型,所以结果是int型,再赋值给short类型s1时,编译器将报告需要强制转换类型的错误。
对于short s1 = 1; s1 += 1;由于 +=运算符里已经包括了一个隐式的强制类型转换,因此Java会把s1+=1计算后的结果进行隐式的强制类型转换,因此它不会有任何错误。
16、char型变量中能不能存储一个中文字符?为什么?
char型变量是用来存储Unicode编码的字符的,Unicode编码字符集中包含了汉字,因此char型变量中可以存储汉字。不过,如果某个特殊的汉字没有被包含在Unicode编码字符集中,那么,这个char型变量中就不能存储这个特殊汉字。
char类型的变量占两个字节,而Unicode编码中每个字符也占两个字节,因此char类型类型的变量可以存储任何一个Unicode字符。
18、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。例如,对于如下语句:
final StringBuilder a=new StringBuilder ("immutable");
执行如下语句将报告编译错误:
a = new StringBuilder ("");
但如下语句则是完全正确的
a.append("fkjava.org");
有人希望在定义方法的形参时,通过final修饰符来阻止方法内部修改传进来的实参:
public void method(final StringBuilder param)
{
}
实际上这没有用,在该方法内部仍然可以增加如下代码来修改实参对象:
param.append("fkjava.org");
19、"=="和equals方法究竟有什么区别?
"=="操作符有两个功能:
A:如果==两边都是基本类型、包装类对象所组成的对象的表达式,比较的是值是否相等,
---只要值相等,即使数据类型不同,该运算符也返回true。
B:两边是引用类型变量,判断是否是引用同一块地址,
而equals()则是一个java.lang.Object类的一个方法,因此任何Java对象都可调用该方法与其他对象进行比较。java.lang.Object类的equals方法的实现代码如下:
boolean equals(Object o)
{
return this==o;
}
从上面代码可以看出,如果一个类没有重写java.lang.Object的equals()
方法时,此时equals()方法的比较结果与==的比较结果是相同的。
但Java允许任何类重写equals()方法,重写该方法就是让程序员来自己决定两个对象相等的标准——极端的情况下,我们完全可以设计出Person对象与Dog对象equals()比较返回true的情况——当然一般不会这么设计。
实际上重写equals()方法时通常会按如下格式
public boolean equals(Object obj){
if(obj == this) return true ;
if(obj == null) return false;
if(obj.getClass() != getClass()){
return false;
}
Cat cat = (Cat)obj;
return name.equals(cat.getName())
&& age.equals(cat.getAge())
&& furColor.equals(cat.getFurColor());
}
上面重写equals()方法用于判断两个Person对象是否“相等”,程序只要两个Person对象的name、pass相等,程序就可以把这两个Person对象当成相等——这是系统业务决定的。如果业务需要,我们也可以增加更多的参与判断的Field,当然也可以只根据name进行判断——只要两个Person的name相等,就认为两个Person相等,这都是由系统的业务决定。
总结起来就是一句话:开发者重写equals()方法就可以根据业务要求来决定两个对象是否“相等”。
22、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.floor(11.6)的结果为11,Math.floor(-11.6)的结果是-12;最难掌握的是round方法,它表示“四舍五入”,算法为Math.floor(x+0.5),即将原来的数字加上0.5后再向下取整,所以,Math.round(11.5)的结果为12,Math.round(-11.5)的结果为-11。
23、请说出作用域public,private,protected,以及不写时的区别
作用于 当前类 同一包(package) 子类 全局
权限大小:private --》default-->protected-->public
作用域 当前类 同一package 子类 全局
public √ √ √ √
protected √ √ √ ×
default √ √ × ×
private √ × × ×
24、外部类能用private、protected修饰吗?内部类可以用private、protected修饰吗?
外部类不能用private、protected修饰。内部类能用private、protected修饰。
外部类的上一级程序单位是包,因此它只有两个使用范围:包内和包外,因此它只能用public(表示可以在全局位置使用)和默认修饰符(default,表示只能被同一个包的其他类使用)修饰。
26、说说has a与is a的区别。
is a是典型的“一般到特殊”的关系,也就是典型的继承关系。例如Apple is a Fruit。那么Apple是一种特殊的Fruit,也就是说Apple继承了Fruit。
has a是典型的“组合”关系。比如Wolf has a Leg,也就是Leg组合成了Wolf。
需要指出的是:由于继承会造成了对父类的破坏,因此有时候可以通过组合来代替的继承。使用继承的好处:程序语义更好理解。坏处是:子类可能重写父类方法,不利于父类封装;使用组合则造成语义的混淆,但组合类不会重写被组合类的方法,因此更利于被复合类的封装。
31、什么时候用assert。
assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下,assert将给出警告或退出。
Java的assert是关键字。
public class TestAssert
{
public static void main(String[] args)
{
int a = 5;
//断言a>3
assert a > 3;
//断言a<3,否则显示a不小于3,且a的值为:" + a
assert a < 3 : "a不小于3,且a的值为:" + a;
}
}
从上面代码可以看出,assert的两个基本用法如下:
assert logicExp;
asert logicExp : expr;
A.第一个直接进行断言,
B.第二个也是进行断言,但当断言失败失败时显示特定信息。
最后要指出:
虽然assert是JDK1.4新增的关键字,但有一点非常重要:
java命令默认不启动断言,
为了启动用户断言,应该在运行java命令时增加-ea(Enable Assert)选项。
为了启动系统断言,应该在运行java命令时增加-esa(Enable System Assert)选项。
33、能不能自己写个类,也叫java.lang.String?
可以,但在应用的时候,需要用自己的类加载器去加载,否则,系统的类加载器永远只是去加载jre.jar包中的那个java.lang.String。
但在Tomcat的web应用程序中,都是由webapp自己的类加载器先自己加载WEB-INF/classess目录中的类,然后才委托上级的类加载器加载,如果我们在Tomcat的web应用程序中写一个java.lang.String,这时候Servlet程序加载的就是我们自己写的java.lang.String,但是这么干就会出很多潜在的问题,原来所有用了java.lang.String类的都将出现问题。
34、ArrayList如何实现插入的数据按自定义的方式有序存放
编程思路:实现一个类对ArrayList进行包装,当成程序试图向ArrayList中放入数据时,程序会先检查元素与ArrayList集合中的其他元素的大小,然后将该元素插入指定位置。
class MyBean implements Comparable{
public int compareTo(Object obj){
if(! obj.instanceof(MyBean))
throw new ClassCastException().
MyBean mb = (MyBean) obj;
return age >mb.age ?1:age==mb.age? 0 : -1;
}
}
classMyTreeSet{
private ArrayList datas = new ArrayList();
public void add(Object obj ){
for(int i=0;i<datas.size();i++){
if(obj.compareTo(datas.get(i) != 1)){
dates.add(i,obj);
}
}
}
}
35.序列化接口的id有什么用?
反序列化Java对象时必须提供该对象的class文件,现在的问题是随着项目的升级,系统的class文件也会升级,Java如何保证两个class文件的兼容性?
Java序列化机制允许为序列化类提供一个private static final的serialVersionUID值,该Field值用于标识该Java类的序列化版本,也就是说如果一个类升级后,只要它的serialVersionUID Field值保持不变,序列化机制也会把它们当成同一个序列化版本。
36、hashCode()方法的作用?
hashCode()方法与equals()方法相似,都是来自java.lang.Object类的方法,都允许用户定义的子类重写这两个方法。
一般来说,equals这个方法是给用户调用的,如果你想根据自己的业务规则来判断2个对象是否相等,你可以重写equals()方法。简单来讲,equals方法主要是用来判断从表面上看或者从内容上看,2个对象是不是相等。
而hashCode()方法通常是给其他类来调用的,比如当我们要把两个对象放入HashSet时,由于HashSet要求两个对象不能相等,而HashSet判断两个对象是否相等的标准是通过equals()比较返回false、或两个对象的hashCode()方法返回值不相等——只要满足任意一个条件都可会认为两个对象不相等。
从这个角度来看,我们可以把hashCode()方法的返回值当成这个对象的“标识符”,如果两个对象的hashCode()相等,即可认为这两个对象是相等的。因此当我们重写一个类的equals()方法时,也应该重写它的hashCode()方法,而且这两个方法判断两个对象相等的标准也应该是一样的。
)