1、请列出Test执行时的输出结果( )

class A
{
    public void printValue()
    {
        System.out.print("A");
    }
}
class S extends A
{
    public void printValue()
    {
        System.out.print("S");
    }
}
public class Test
{
    public static void main(String[] args)
    {
        S s = new S();
        s.printValue();
        A as = (A)s;
        as.printValue();
        as = new A();
        as.printValue();
    }
}

A 编译不通过
B SSA
C SSS
D SAA

答案是:B

解析:

类S继承自A,子类继承父类成员方法时,如果在子类中出现了同名称的成员方法,则称为覆盖,即子类的成员方法会覆盖掉父类的同名成员方法。因此,对象s调用printValue方法时,会使用子类中的方法,也就是print("S")。
as.printValue()语句考查的是隐藏和覆盖的区别。覆盖只针对非静态方法,而隐藏是针对成员变量和静态方法的。这两者者之间的区别是:覆盖受RTTI(Runtime type identification)约束,而隐藏却不受该约束,也就是说只有覆盖方法才会进行动态绑定,而隐藏是不会发生动态绑定的。在Java中,除了static方法和final方法,其他所有的方法都是动态绑定。所以as.printValue()的结果是print("S")。
最后,as=new A()语句中,自然执行的是print("A")。

2、下段程序运行的结果是( )

class MyThread2 implements Runnable
{
    Public static void main(String[ ] args)throws interruptedException
    {
        Thread t = new Thread(new MyThread2( ));
        t.start( );
        System.out.print("m1");
        t.join( );
        System.out.print("m2");
    }

    public void run( )
    {
        System.out.print("r1");
        System.out.print("r2");
    }
}

A 程序输出结果是r1 r2 m1 m2
B 程序输出结果是m1 m2 r1 r2
C 程序输出结果是m1 r1 r2 m2
D 程序输出结果是m1 r1 m2 r2
E runtime error

答案是:C

解析:

一个线程可以拥有就绪 (可运行) 状态、运行状态和阻塞状态。在该题中,JVM 以 main() 方法为切入点,产生主线程 m。接着new了一个线程 t 并调用start()方法启动线程,使得线程t进入可运行状态,等待被执行。需要注意的是,此时的线程 t 只是可运行状态,而不是运行状态,此时会继续执行第一个打印语句,打印出 m1。接着t.join() 方法使得主线程m等待子线程t运行完毕之后再继续运行。因此,线程t 进入运行状态,执行run() 方法,顺序打印出 r1 r2。当线程 t 执行完毕后,执行最后一个打印语句,打印出 m2。


登陆发表评论