Java面试题大全(Java基础十)

11 篇文章 0 订阅

46、内部类可以引用它的外部类的成员吗?有没有什么限制?

内部类可以访问所在外部类的成员。
但有一点需要注意:静态成员不能访问非静态成员,因此静态内部类(属于静态成员)就不能访问外部类的非静态成员。

47、Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?

可以继承其他类或实现其他接口。而且由于匿名内部类特殊的语法:
new 父类|父接口()
{
类体实现部分
}
从上面语法不难看出,匿名内部类必须继承其他类或实现其他接口。

48、super.getClass()方法调用
下面程序的输出结果是多少?

import java.util.Date;
public class Test extends Date{
    public static void main(String[] args) {
        new Test().test();
    }
    public void test(){
        System.out.println(super.getClass().getName());
    }
}

程序输出的是Test。

解释:super它只是一个限定词,当用super引用时,它也是引用当前对象本身,只是super只是限定了访问当前对象从父类那里继承得到成员变量或方法。
如果需要访问父类的类名,应该使用如下语法:
super.getClass().getSuperclass().getName()

  1. JDK中哪些类是不能继承的?

不能继承的是类是那些用final关键字修饰的类。
实际上即使我们自己开发的类,也可以通过使用final修饰来阻止被继承。通过使用final修饰一个类,可以阻止该类被继承,这样该类就被完全地封闭起来了,不会有子类来重写它的方法,因此更加安全。

50、String s = “Hello”;s = s + ” world!”;这两行代码执行后,原始的String对象中的内容到底变了没有?
没有。因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。在这段代码中,s原先指向一个String对象,内容是 “Hello”,然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个 String对象,内容为”Hello world!”,原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。
通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为 String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。
实际上,当我们需要一个字符串对象时,应该使用如下语法来创建String对象:
Sring s = “fkjava.org”;
也就是直接使用字符串直接量的语法。而不是:
String s = new String(“fkjava.org”);
对于第二种语法而言,每次都会调用构造器生成新的String对象,性能低下且内存开销大,并且没有意义,因为String对象不可改变,所以对于内容相同的字符串,只要一个String对象来表示就可以了。
基于这样一种想法,Java提供了字符串缓存池来管理字符串直接量,当程序多次用到同一个字符串直接量时,系统会让它们都引用字符串缓存池中的同一个String对象。因此使用在程序中使用字符串直接量可以充分利用这个特性来降低系统内存开销,提高程序性能。

51、是否可以继承String类?
String类是final类,不可以被继承。

52、如何把一段逗号分割的字符串转换成一个数组?
A. 在以前的时候,Java提供了一个StingTokenizer工具类来处理字符串分割的问题。比如使用如下语法:

StringTokenizer st = new StringTokenizer("this,is,a,test" , ",");
while (st.hasMoreTokens()) 
{
    System.out.println(st.nextToken());
}

这样程序将会输出
this
is
a
test

B. 后来Java为String类增加了正则表达式支持,StingTokenizer基本上没用了。因此上面代码可以简写为:
String [] result = “this,is,a,test”.split(“,”);
其中result数组中就存放了this、is、a、test等字符串元素。

53、下面这条语句一共创建了多少个对象:String s=”a”+”b”+”c”+”d”;
答:对于如下代码:
String s1 = “a”;
String s2 = s1 + “b”;
String s3 = “a” + “b”;
System.out.println(s2 == “ab”);
System.out.println(s3 == “ab”);
第一条语句打印的结果为false,第二条语句打印的结果为true。
Java会在编译时对字符串相加进行优化处理,如果整个表达式中所有参与运算的都是字符串直接量,Java会在编译时就把这个表达式的值计算出来,然后直接将结果赋值给字符串引用变量。因此上面题目中定义的String s = “a” + “b” + “c” + “d”;实际上相当于直接定义了”abcd”的字符串直接量,所以,上面的代码应该只创建了一个String对象。
而且这个字符串直接量会被放入字符串缓存池中。如下两行代码,
String s = “a” + “b” + “c” + “d”;
System.out.println(s == “abcd”);
由于s引用了字符串缓存池中的”abcd”字符串,因此上面输出结果应该为true。

54、Collection框架中实现比较要实现什么接口
Java集合框架中需要比较大小的集合包括TreeMap、TreeSet,其中TreeMap会根据key-value对中key的大小进行排序,而TreeSet则会对集合元素进行排序。
因此TreeMap的key、TreeSet的集合元素,都需要可以比较大小。集合框架中之比较大小的有两种方式:
A.自然排序:对于自然排序来说,要求TreeMap中的所有key都实现Comparable接口,实现该接口时需要实现一个int compareTo(T o)方法,用于判断当前对象与o对象之间的大小关系。如果该方法返回正整数,则说明当前对象大于o对象;如果该方法返回0,说明两个对象相等;如果该方法返回负整数,则说明当前对象小于o对象;JDK的很多类都已经实现了Comparable接口,例如String、Date、BigDecimal等。
B.定制排序:定制排序需要在创建TreeMap或TreeSet时传入一个Comparator对象,此时TreeMap或TreeSet不再要求key、集合元素本身是可比较大小的,而是由Comparator来负责比较集合元素的大小。Comparator本身只是一个接口,因此创建Comparator对象只能是创建它的实现类的对象,Comparator的实现类需要实现int compare(T o1, T o2)方法,该方法用于判断o1、o2两个对象的大小,如果该方法返回正整数,则说明o1大于o2、如果该方法返回负整数,则说明o1小于o2、如果返回0,则说明两个对象相等。

55、ArrayList和Vector的区别
这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素,并且其中的数据是允许重复的——这是由List集合规范制订的。
而且ArrayList与Vector底层都是基于数组的,因此它们的实现代码也大致相似。区别在于Vector是一个古老的集合,从JDK1.0开始就有了,因此它包含了大量方法名很长的方法,JDK 1.2开始引入集合框架,引入List接口,才让Vector实现了List接口,因此又增加了一些List接口中定义的方法。总体来说,ArrayList可以完全代替Vector,除了在一些很古老的API中强制要求使用Vector之外。
Vector还有一个特征:它是线程安全的,因此性能比较差。而ArrayList并不是线程安全的,因此性能较好。实际上即使我们要在多线程环境下使用List集合,也应该选择ArrayList,而不是Vector,因为Java还提供了一个Collections工具类,它可以把ArrayList包装成线程安全的集合类,例如如下代码:
List list = Collections.synchronizedList(new ArrayList());

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值