java面试题之后续答案

匿名网友 匿名网友 发布于: 2015-08-30 00:00:00
阅读 152 收藏 0 点赞 0 评论 0

1.hashCode()作用
答:在实现Hash算法的集合里面,例如HashSet,该集合不能存放相同的数据,HashSet会根据对象的equals()和hashCode()方法来判断要存放的数据是否已经存在。Hash算法把HashSet划分成多个区域,每个区域就是以哈希码来作为该区域的唯一编码,而hashCode()的作用就是为某对象生成一个哈希码。Hash算法会认为如果两个对象的equals()比较后相等,那么它所对应的hashCode也应该相等,那么
HashSet会从该哈希码所对应的那个区域来查找是否已经存在该对象数据,不存在则放进去。而如果只提供equals方法,不提供hashCode()方法,就算判断出两个对象引用相等,但是HashSet会在不同的区域下寻找是否有该对象,这样,HashSet会把相同的对象引用存放在两个不同的区域里面。
注意:只有实现了Hash算法的集合hashCode才起作用。

2.Java类会造成内存的泄露吗?为什么?
答:会
例如:Set set = new HashSet();
ReflectPoint rp = new ReflectPoint(3,4);
//测试对象,根据其x,y属性来算出hashCode
set.add(rp);
如果现在不需要rp数据了,想从内存中删除掉该对象引用,可以用
set.remove(rp);
此时可以清理出内存空间。
但是如果修改了hashCode生成的x,y属性:
rp.x = 66;
此时调用set.remove(rp);,则无法删除该对象引用,因为改变了x属性的值,其
hashCode也会改变,假如本来rp对象存放在A区域里面,hashCode一变,此时set.remove(rp)会从改变后的hashCode所对应的那个区域下寻找是否存在rp对象,存在就删除,而此时并不能找到,则不能删除掉,rp对象引用还会存放在内存中,占用内存空间,不被释放,造成内存的泄露。
建议:不要轻易修改用于生成hashCode的属性。

3.Java能不能自己写个类叫java.lang.System类?
答:一般不行,根本原因是受到类加载器的委托机制影响。
大家都知道,每个Java类都需要一个类加载器把编译好的class文件加载进内存中生成一份字节码。而JVM中主要有三种类加载器,这三个类加载器是父子关系(parent->children):
BootStrap(负责加载JVM下jre/lib/rt.jar),
ExtClassLoader(负责加载jre/lib/ext/*.jar),
AppClassLoader(负责加载classpath指定的jar或目录)
说到这里,大家也许会问,那么最终的父加载器BootStrap由谁加载呢?这个疑问大家不必担心,其实BootStrap并不是一个Java类,它是由C语言编写的一个含有加载Java类功能的文件,受类加载器的委托机制影响,就算用户编写了一个java.lang.System类,那么它会通过AppClassLoader找到父ExtClassLoader,再找BootStrap,从BootStrap开始加载,如果加载不到才会回调给其子加载器去加载,而BootStrap加载的rt.jar中就包含了这个System类,所以就算用户自己编写了自己的System类,
JVM也会先找到BootStrap加载器下的System类,并不会加载用户所编译的System类。
如果你真的想编写一个System类,就只能通过修改类加载器的委托机制去影响类的加载了。呵呵,不过这基本上是妄想。

4.Java5的新特性?
答:a.可变参数
b.foreach语句
c.泛型generic
d.枚举enum
e.注解annotation
这里就不详解了,有兴趣的自己去看书。

5.你能够通过什么方法来获取到参数化类型(泛型)的实际类型参数?
答:
public class GenericTest {
/**
* @param args
*/
public static void main(String[] args) throws Exception{
//第二步:获取泛型的实际的类型参数
Method method = GenericTest.class.getMethod(“applyGeneric”, Vector.class);
Type[] types = method.getGenericParameterTypes();
//因为本例知道参数只有一个,所以直接简写下标[0]获取第一个
ParameterizedType pType = (ParameterizedType)types[0];
System.out.println(pType.getRawType());
System.out.println(pType.getActualTypeArguments()[0]);//实际的类型参数
}
//通过反射机制来获取到泛型中的类型参数实例
//因为泛型完全是应用于编译器的,当类加载器加载class文件进内存时,会自动擦除泛型信息,字节码中无泛型类型信息
//所以普通方法无法获取到该类型参数,可以采用反射中Method对象中的获取泛型参数列表方法获取
//第一步:定义一个应用泛型的方法
public static void applyGeneric(Vector<Date> v){

}
}

评论列表
文章目录