Java面试题集(二)

51、设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1,写出程序。 

以下程序使用内部类实现线程,对j增减的时候没有考虑顺序问题。

public class ThreadTest1 {

   private int j;

   public static void main(String args[]){

   ThreadTest1 tt=new ThreadTest1();

       Inc inc=tt.new Inc();

       Dec dec=tt.new Dec();

       for(int i=0;i<2;i++){

           Thread t=new Thread(inc);

           t.start();

      t=new Thread(dec);

           t.start();

       }

   }

   private synchronized void inc(){

      j++;

       System.out.println(Thread.currentThread().getName()+"-inc:"+j);

   }

   private synchronized void dec(){

       j--;

       System.out.println(Thread.currentThread().getName()+"-dec:"+j);

   }

   class Inc implements Runnable{

   public void run(){

       for(int i=0;i<100;i++){

       inc();

       }

   }

}

class Dec implements Runnable{

   public void run(){

       for(int i=0;i<100;i++){

       dec();

       }

   }

}

} 

52、ArrayList和Vector的区别

它们都实现了list接口,都是集合类,存储数据是有序的,底层是以数组形式存储,都可以按照索引位置取出元素,并且数据可以重复

(1)同步性:

Vector是线程安全的,也就是说是它的方法之间是线程同步的,而ArrayList是线程序不安全的,它的方法之间是线程不同步的。如果只有一个线程会访问到集合,那最好是使用ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好是使用Vector,

(2)数据增长:

Vector增长原来的一倍,ArrayList增加原来的0.5倍。

53、HashMap和Hashtable的区别?

两者都是实现Map接口

1.HashMap允许键和值是null,而hashtable不允许键和值是null

2.HashMap是线程不安全的,HashTable是线程安全的。Hashmap通过get(key)得到元素,那么内部是通过哈希算法做到的,HashMap通过键的hashCode来快速的存取元素。

54.HashMap和HashSet的区别?

1.HashSet底层是用HashMap实现的,HashMap实现map接口,HashSet实现set接口

public HashSet() {

map = new HashMap<E,Object>();

}

2.HashMap添加元素用put(key,value),而HashSet添加元素用add(key)

3.HashMap使用键对象来计算hashcode值,而HashSet使用成员对象来计算hashcode值

4.HashMap存储键值对,而HashSet仅仅存储对象

5.HashMap执行效率比HashSet高。

55.Java中HashMap工作原理?

Java中HashMap是以键值对(key-value)的形式存储元素的。HashMap需要一个hash函数,它使用hashCode()和equals()方法来向集合添加和检索元素。当调用put()方法的时候,HashMap会计算key的hash值,然后把键值对存储在集合中合适的索引上。如果key已经存在了,Value会被更新成新值。

Java中HashMap使用hashCode()和equals()方法来确定键值对的索引,当根据键获取值的时候也会用到这个方法。如果没有正确的实现这两个方法,两个不同的键可能会有相同的hash值,因此可能会被集合认为是相等的。而且这两个方法也用来发现重复元素。

56.Hashmap多线程下如何解决并发问题?

1:在外部包装HashMap,实现同步机制。

2:使用Map m = Collections.synchronizedMap(new HashMap(...));,这里就是对HashMap做了一次包装

3:使用java.util.HashTable,效率最低(线程安全)

4:使用java.util.concurrent.ConcurrentHashMap,相对安全,效率较高

57.Java中hashmap遍历的2种方法:keySet()和entrySet()

第一种:效率高,一定要经常用

Map map=new HashMap();

Iterator it=map.entrySet().iterator();

while(it.hasNext()){

Map.Entry entry=(Map.Entry)it.next();

Object key=entry.getKey();

Object value=entry.getValue();

}

第二种:效率低,尽量少用

Map map=new HashMap();

Iterator it=map.keySet().iterator();

while(it.hasNext()){

Object key=it.next();

Object value=map.get(key);

58、List 和 Map 区别?

一个是存储单列数据的集合,另一个是存储键和值这样的双列数据的集合,List中存储的数据是有顺序,并且允许重复;Map中存储的数据是没有顺序的,其键是不能重复的,它的值是可以有重复的。

59、List、Map、Set三个接口存取元素时各有什么特点? 

List与Set它们都是单列元素的集合,所以它们有一个功共同的父接口Collection。Set有序存储数据,且不允许有重复的元素,List有序存储数据,且元素可以重复。

Map是双列集合,实现Map接口而不是Collcetion接口,无序存储数据,存储数据为键值对,键不能重复,值可以重复,键和值都可以为null。

60、说出ArrayList,Vector, LinkedList的存储性能和特性 

ArrayList和Vector都是使用数组方式存储数据,它们都允许直接按序号索引元素,查询数据快而插入数据慢。

Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,

LinkedList使用双向链表实现存储,插入速度较快。

61、去掉一个Vector集合中重复的元素 ?

Vector newVector = new Vector();

For (int i=0;i<vector.size();i++){

Object obj = vector.get(i);

if(!newVector.contains(obj);

newVector.add(obj);

}

还有一种简单的方式,HashSet set = new HashSet(vector);

62、Collection 和 Collections的区别。 

Collection是集合类的上级接口,继承与他的接口主要有Set 和List

Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

63、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别? 

Set里的元素是不能重复的,元素重复与否是使用equals()方法进行判断的。

equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。

64、两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对? 

对。

如果对象要保存在HashSet或HashMap中,它们的equals相等,那么,它们的hashcode值就必须相等。

如果不是要保存在HashSet或HashMap,则与hashcode没有什么关系了,这时候hashcode不等是可以的,例如arrayList存储的对象就不用实现hashcode,当然,我们没有理由不实现,通常都会去实现的。

65、java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类? 

字节流,字符流。字节流继承于InputStream OutputStream,字符流继承于InputStreamReader OutputStreamWriter。在java.io包中还有许多其他的流,主要是为了提高性能和使用方便。

66、解释内存中的栈(stack)、堆(heap)和静态存储区的用法?(Java创建对象如何存储的?)

通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用内存中的栈空间;而通过new关键字和构造器创建的对象放在堆空间;程序中的字面量(literal)如直接书写的100、“hello”和常量都是放在静态存储区中。栈空间操作最快但是也很小,通常大量的对象都是放在堆空间,整个内存包括硬盘上的虚拟内存都可以被当成堆空间来使用。

String str = new String(“hello”);

上面的语句中str放在栈上,用new创建出来的字符串对象放在堆上,而“hello”这个字面量放在静态存储区。

67、什么是java序列化,如何实现java序列化?或者请解释Serializable接口的作用。 

我们有时候将一个java对象变成字节流的形式传出去或者从一个字节流中恢复成一个java对象,例如,要将java对象存储到硬盘或者传送给网络上的其他计算机,这个过程我们可以自己写代码去把一个java对象变成某个格式的字节流再传输,但是jre本身就提供了这种支持,我们可以调用OutputStream的writeObject方法来做,如果要让java
帮我们做,要被传输的对象必须实现serializable接口,这样javac编译时就会进行特殊处理,编译的类才可以被writeObject方法操作,这就是所谓的序列化。需要被序列化的类必须实现Serializable接口,其中没有需要实现的方法,implements
Serializable只是为了标注该对象是可被序列化的。

例如在web开发中,如果对象被保存在了Session中,tomcat在重启时要把Session对象序列化到硬盘,这个对象就必须实现Serializable接口。如果对象要经过分布式系统进行网络传输,这就需要在网络上传输对象,被传输的对象就必须实现Serializable接口。

68、描述一下JVM加载class文件的原理机制? 

JVM中类的装载是由ClassLoader和它的子类来实现的,Java ClassLoader 是一个重要的Java运行时系统组件。它负责在运行时查找和装入类文件的类。

69、heap和stack有什么区别?

java的内存分为两类,一类是栈内存,一类是堆内存。栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。

堆是与栈作用不同的内存,一般用于存放不放在当前方法栈中的那些数据,例如使用new创建的对象都放在堆里,所以它不会随方法的结束而消失。方法中的局部变量使用final修饰后,放在堆中,而不是栈中。

70、GC是什么? 为什么要有GC? 

GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。

71、垃圾回收的优点和原理。并考虑2种回收机制。 

Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有"作用域"的概念,只有对象的引用才有"作用域"。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。

72、垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收? 

对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常GC采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当GC确定一些对象为"不可达"时,GC就有责任回收这些内存空间。程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。

73、什么时候用assert?

assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下,assert将给出警告或退出。一般来说,assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后,assertion检查通常是关闭的。

package com.huawei.interview;

public class AssertTest {

public static void main(String[] args) {

int i = 0;

for(i=0;i<5;i++){

System.out.println(i);

}

//假设程序不小心多了一句--i;

--i;

assert i==5;

}

}

74、java中会存在内存泄漏吗? 

所谓内存泄露就是指一个不再被程序使用的对象或变量一直被占据在内存中。java中有垃圾回收机制,它可以保证一对象不再被引用的时候,即对象编程了孤儿的时候,对象将自动被垃圾回收器从内存中清除掉。由于Java 使用有向图的方式进行垃圾回收管理,可以消除引用循环的问题,例如有两个对象,相互引用,只要它们和根进程不可达的,那么GC也是可以回收它们的,例如下面的代码可以看到这种情况的内存回收:

package com.huawei.interview;

import java.io.IOException;

public class GarbageTest {

public static void main(String[] args) throws IOException {

try {

gcTest();

} catch (IOException e) {

    e.printStackTrace();

}

System.out.println("has exited gcTest!");

System.in.read();

System.in.read();

System.out.println("out begin gc!");

for(int i=0;i<100;i++){

System.gc();

System.in.read();

System.in.read();

}

}

private static void gcTest() throws IOException {

System.in.read();

System.in.read();

Person p1 = new Person();

System.in.read();

System.in.read();

Person p2 = new Person();

p1.setMate(p2);

p2.setMate(p1);

System.out.println("before exit gctest!");

System.in.read();

System.in.read();

System.gc();

System.out.println("exit gctest!");

}

  private static class Person{

byte[] data = new byte[20000000];

Person mate = null;

public void setMate(Person other){

mate = other;

}

}

}

java中的内存泄露的情况:长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是java中内存泄露的发生场景,通俗地说,就是程序员可能创建了一个对象,以后一直不再使用这个对象,这个对象却一直被引用,即这个对象无用但是却无法被垃圾回收器回收的,这就是java中可能出现内存泄露的情况,例如,缓存系统,我们加载了一个对象放在缓存中(例如放在一个全局map对象中),然后一直不再使用它,这个对象一直被缓存引用,但却不再被使用。

检查java中的内存泄露,一定要让程序将各种分支情况都完整执行到程序结束,然后看某个对象是否被使用过,如果没有,则才能判定这个对象属于内存泄露。

如果一个外部类的实例对象的方法返回了一个内部类的实例对象,这个内部类对象被长期引用了,即使那个外部类实例对象不再被使用,但由于内部类持久外部类的实例对象,这个外部类对象将不会被垃圾回收,这也会造成内存泄露。

内存泄露的另外一种情况:当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象,造成内存泄露。

75、写一个Singleton出来。(面试必考)

Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。

第一种:饱汉模式

public class SingleTon {

private SingleTon(){//私有化构造方法

}

//实例化放在静态代码块里可提高程序的执行效率,但也可能更占用空间

//创建私有静态当前对象,注意这是private 只供内部调用

private final static SingleTon instance = new SingleTon();

//返回当前对象,这里提供了一个供外部访问本class的静态方法,可以直接访问

public static SingleTon getInstance(){

return instance;

}

}

第二种:饥汉模式

public class SingleTon {

private SingleTon(){}

//创建静态对象为null

private static instance = null;

//保证返回当前方法线程同步

//这个方法比上面有所改进,不用每次都进行生成对象,只是第一次     

//使用时生成实例,提高了效率!

public static synchronized SingleTon getInstance(){

if(instance == null){

instance = new SingleTon();

}

return instance;

}

}

备注:首先说下单例模式好处,然后自己一定要写出2中单例模式,这样可以体现出你技术水平,而不是背面试得出来的,当前若是结合你实际工作中运用那么会更好。

76.
常见笔试题Java代码查错

1.

abstract class Name {
   private String name;
   public abstract boolean isStupidName(String name) {}
}

答案: 错。编译不通过,abstract method必须以分号结尾,且不带花括号。

2.

public class Something {
   void doSomething () {
    private String s = "";
    int l = s.length();
   }
}

答案: 错。局部变量前不能放置任何访问修饰符 (private,public和protected)。final可以用来修饰局部变量,

final如同abstract都是非访问修饰符。

3.

abstract class Something {
   private abstract String doSomething ();
}

答案: 错。abstract的methods不能以private修饰。abstract的methods就是让子类implement(实现)具体细节的,抽象类修饰符为public或者protected。

4.

public class Something {
   public int addOne(final int x) {
       return ++x;
   }
}

答案: 错。int x被修饰成final,意味着x不能在addOne method中被修改。

5.

public class Something {
   public static void main(String[] args) {
       Other o = new Other();
       new Something().addOne(o);
   }
   public void addOne(final Other o) {
       o.i++;
   }
}
class Other {
   public int i;
}

答案: 正确。在addOne method中,参数o被修饰成final。如果在addOne method里我们修改了o的指向为o=new Other();

那么就是错误错的,但这里修改的是o的成员变量而o的指向并没有改变。

6.

class Something {
    int i;
    public void doSomething() {
        System.out.println("i = " + i);
    }
}

答案: 正确。输出的是"i = 0"。int i属于实例变量或叫成员变量),实例变量有默认值。int的默认是0。

这里就考察int与Integer的区别了,int是基本数据类型,默认值为0,而Integer是包装类型,默认值为null

7.

class Something {
    final int i;
    public void doSomething() {
        System.out.println("i = " + i);
    }
}

答案: 错。final int i是个final的实例变量或叫成员变量)。final的实例变量没有默认值,必须在构造器结束之前被赋予一个明确的值。可以修改为"final int i = 0;"。

8.

public class Something {
     public static void main(String[] args) {
        Something s = new Something();
        System.out.println("s.doSomething() returns " + doSomething());
    }
    public String doSomething() {
        return "Do something ...";
    }
}

答案: 错。看上去在main里call doSomething没有什么问题,毕竟两个methods都在同一个class里。但仔细看,main是static的。静态方法能直接访问非静态方法。可改成"System.out.println("s.doSomething() returns
" + s.doSomething());"。同理,静态方法不能访问非静态方法的成员变量或者实例变量。

这里考察知识点:静态方法与非静态方法的区别,静态方法时类的方法,直接通过类名调用,而非静态方法必须创建实例对象,通过实例对象引用才能调用里面方法。

9.

此处,Something类的文件名叫OtherThing.java

class Something {
    private static void main(String[] something_to_do) {
        System.out.println("Do something ...");
    }
}

答案: 正确。从来没有人说过Java的Class名字必须和其文件名相同。但public class的名字必须和文件名相同。

10.

interface  A{
   int x = 0;
}
class B{
   int x =1;
}
class C extends B implements A {
   public void pX(){
      System.out.println(x);
   }
   public static void main(String[] args) {
      new C().pX();
   }
}

答案:错误。在编译时会发生错误(错误描述不同的JVM有不同的信息,意思就是未明确的x调用,两个x都匹配(就像在同时import java.util和java.sql两个包时直接声明Date一样)。对于父类的变量,可以用super.x来明确,而接口的属性默认隐含为 public
static final.所以可以通过A.x来明确。

11.

interface Playable {
    void play();
}
interface Bounceable {
    void play();
}
interface Rollable extends Playable, Bounceable {
    Ball ball = new Ball("PingPang");
}
class Ball implements Rollable {
    private String name;
    public String getName() {
        return name;
    }
    public Ball(String name) {
        this.name = name;
    }
   public void play() {
        ball = new Ball("Football");
        System.out.println(ball.getName());
    }
}

这个错误不容易发现。

答案: 错。"interface Rollable extends Playable, Bounceable"没有问题。interface可继承多个interfaces,所以这里没错。问题出在interface Rollable里的"Ball ball = new Ball("PingPang");"。任何在interface里声明的interface variable (接口变量,也可称成员变量),默认为public static final。也就是说"Ball
ball = new Ball("PingPang");"实际上是"public static final Ball ball = new Ball("PingPang");"。在Ball类的Play()方法中,"ball = new Ball("Football");"改变了ball的指向,而这里的ball来自Rollable interface,Rollable interface里的ball是public
static final的,final的object是不能被改变指向的。因此编译器将在"ball = new Ball("Football");"这里显示有错。

时间: 2024-10-12 16:39:02

Java面试题集(二)的相关文章

转:Java面试题集(51-70) http://blog.csdn.net/jackfrued/article/details/17403101

Java面试题集(51-70) Java程序员面试题集(51-70) http://blog.csdn.net/jackfrued/article/details/17403101 摘要:这一部分主要讲解了异常.多线程.容器和I/O的相关面试题.首先,异常机制提供了一种在不打乱原有业务逻辑的前提下,把程序在运行时可能出现的状况处理掉的优雅的解决方案,同时也是面向对象的解决方案.而Java的线程模型是建立在共享的.默认的可见的可变状态以及抢占式线程调度两个概念之上的.Java内置了对多线程编程的支

Java面试题集(1-50)

说明:最近已经重新发布了最新的<Java面试题大全>,欢迎大家点击浏览. 下面的内容是对网上原有的Java面试题集及答案进行了全面修订之后给出的负责任的题目和答案,原来的题目中有很多重复题目和无价值的题目,还有不少的参考答案也是错误的,修改后的Java面试题集参照了JDK最新版本,去掉了EJB 2.x等无用内容,补充了数据结构和算法相关的题目.经典面试编程题.大型网站技术架构.操作系统.数据库.软件测试.设计模式.UML等内容,同时还对很多知识点进行了深入的剖析,例如hashCode方法的设计

java高级工程师开放面试题集&lt;二&gt;

临近年关,不少人蠢蠢欲动,有童鞋问我java后端面试会面试什么? 作为一个java后端老鸟,跌打滚爬多次被面试和面试别人,总结了一些经验,希望对大家有所帮助. 特别说明,仅仅针对工作两年以上的java后端开发.以开放性题目为主,没有标准答案. 上篇<java高级工程师开放面试题集<一>> 本次是第二篇: 6.缓存相关 如何设计实现LRU缓存? Least Recently Used,最近最少使用缓存. 思路: 6.1.每个key 需要有value,最近的使用时间戳 6.2.面向对象

2015 Java面试题集

Rock 不会直接公布答案.好记性不如烂笔头,烂笔头不如动手敲代码.需要答案的朋友请把试题做一遍,再把答案发我邮件([email protected]).Rock 会在一周内给你回复.也许你的解答会给 Rock 新的启发. 试题集A 1.质数是指该数除1之外没有其他因子,试写出一个方法用于判断一个整数是否为质数: 2.删除输入字符串中的数字并压缩字符串,例如输入字符串“abc123de4fg56"处理后输出结果为”abcdefg". 3.写一个方法 makeArray 负责创建并返回一

转:Java面试题集(1-50)

Java程序员面试题集(1-50) http://blog.csdn.net/jackfrued/article/details/17403101 一.Java基础部分 1.面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: 1)抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么. 2)继承:继承是从已有类得到继承信息创建新类的过程.提供继承信息的类被称为父类(超类.基类):得到继承信息

java面试题集2

JAVA面试题-CORE JAVA部分          1.  在main(String[] args)方法内是否可以调用一个非静态方法? 答案:不能 2.  同一个文件里是否可以有两个public类? 答案:不能 3.  方法名是否可以与构造器的名字相同?   答案:可以. public class Test {        public Test(String iceboy)        {                System.out.println(iceboy);     

大公司的Java面试题集

找工作要面试,有面试就有对付面试的办法.以下一些题目来自我和我朋友痛苦的面试经历,提这些问题的公司包括IBM, E*Trade, Siebel, Motorola, SUN, 以及其它大小公司. 面试是没什么道理可讲的,它的题目有的不合情理.脱离实际.有在纸上写的,有当面考你的,也有在电话里问的,给你IDE的估计很少(否则你赶快去买彩票, 说不定中).所以如果你看完此文后,请不要抱怨说这些问题都能用IDE来解决.你必须在任何情况下准确回答这些问题,在面试中如果出现一两题回答不准确很有可能你就被拒

Java面试题集

前几天,有朋友去面试之前问我关于后端架构相关的问题,但奈于我去年很多其它的工作是在移动SDK开发上,对此有所遗忘,实属无奈,后面准备总结下. 今天要谈的主题是关于求职.求职是在每一个技术人员的生涯中都要经历多次,对于我们大部分人而言,在进入自己心仪的公司之前少不了准备工作,有一份全面仔细面试题将帮助我们降低很多麻烦.在跳槽季来临之前,特地做这个系列的文章,一方面帮助自己巩固下基础,还有一方面也希望帮助想要换工作的朋友. 从12年開始,我先后做过爬虫,搜索,机器学习,javaEE及Android等

java面试题整理二(转灰灰+灰灰)

java 开发面试题小整理(二) 51.Anonymous Inner Class(匿名内部类)是否可以继承其它类?是否可以实现接口? 答:可以继承其他类或实现其他接口,在Swing编程和Android开发中常用此方式来实现事件监听和回调. 52.内部类可以引用它的包含类(外部类)的成员吗?有没有什么限制? 答:一个内部类对象可以访问创建它的外部类对象的成员,包括私有成员. 53.Java 中的final关键字有哪些用法? 答:(1)修饰类:表示该类不能被继承: (2)修饰方法:表示方法不能被重