Java面试宝典基础部分26-30题

26、abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?      abstract的me…

26、abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?

     abstract的method 不可以是static的,因为抽象的方法是要被子类实现的,而static与子类扯不上关系!

     native方法表示该方法要用另外一种依赖平台的编程语言实现的,不存在着被子类实现的问题,所以,它也不能是抽象的,不能与abstract混用。例如,FileOutputSteam类要硬件打交道,底层的实现用的是操作系统相关的api实现,例如,在windows用c语言实现的,所以,查看jdk 的源代码,可以发现FileOutputStream的open方法的定义如下:

  private native void open(String name) throws FileNotFoundException;

    如果我们要用java调用别人写的c语言函数,我们是无法直接调用的,我们需要按照java的要求写一个c语言的函数,又我们的这个c语言函数去调用别人的c语言函数。由于我们的c语言函数是按java的要求来写的,我们这个c语言函数就可以与java对接上,java那边的对接方式就是定义出与我们这个c函数相对应的方法,java中对应的方法不需要写具体的代码,但需要在前面声明native。

    关于synchronized与abstract合用的问题,我觉得也不行,因为在我几年的学习和开发中,从来没见到过这种情况,并且我觉得synchronized应该是作用在一个具体的方法上才有意义。而且,方法上的synchronized同步所使用的同步锁对象是this,而抽象方法上无法确定this是什么。

    27、什么是内部类?Static Nested Class 和 Inner Class的不同。

    内部类就是在一个类的内部定义的类,内部类中不能定义静态成员(静态成员不是对象的特性,只是为了找一个容身之处,所以需要放到一个类中而已,这么一点小事,你还要把它放到类内部的一个类中,过分了啊!提供内部类,不是为让你干这种事情,无聊,不让你干。我想可能是既然静态成员类似c语言的全局变量,而内部类通常是用于创建内部对象用的,所以,把“全局变量”放在内部类中就是毫无意义的事情,既然是毫无意义的事情,就应该被禁止),内部类可以直接访问外部类中的成员变量,内部类可以定义在外部类的方法外面,也可以定义在外部类的方法体中,如下所示:

public class Outer
{
         int out_x  = 0;
         public void method()            {
               Inner1 inner1 = new Inner1();
               public class Inner2   //在方法体内部定义的内部类
               {
                     public method()
                     {
                           out_x = 3;
                     }
               }
               Inner2 inner2 = new Inner2();
         }
 
         public class Inner1   //在方法体外面定义的内部类
         {
         }
         
}

    在方法体外面定义的内部类的访问类型可以是public,protecte,默认的,private等4种类型,这就好像类中定义的成员变量有4种访问类型一样,它们决定这个内部类的定义对其他类是否可见;对于这种情况,我们也可以在外面创建内部类的实例对象,创建内部类的实例对象时,一定要先创建外部类的实例对象,然后用这个外部类的实例对象去创建内部类的实例对象,代码如下:

Outer outer = new Outer();
Outer.Inner1 inner1 = outer.new Innner1();

    在方法内部定义的内部类前面不能有访问类型修饰符,就好像方法中定义的局部变量一样,但这种内部类的前面可以使用final或abstract修饰符。这种内部类对其他类是不可见的其他类无法引用这种内部类,但是这种内部类创建的实例对象可以传递给其他类访问。这种内部类必须是先定义,后使用,即内部类的定义代码必须出现在使用该类之前,这与方法中的局部变量必须先定义后使用的道理也是一样的。这种内部类可以访问方法体中的局部变量,但是,该局部变量前必须加final修饰符。

Java面试宝典基础部分

    对于这些细节,只要在eclipse写代码试试,根据开发工具提示的各类错误信息就可以马上了解到。

    在方法体内部还可以采用如下语法来创建一种匿名内部类,即定义某一接口或类的子类的同时,还创建了该子类的实例对象,无需为该子类定义名称:

public class Outer
{
         public void start()
         {
               new Thread(
new Runable(){
                           public void run(){};
}
).start();
         }
}

    最后,在方法外部定义的内部类前面可以加上static关键字,从而成为Static Nested Class,它不再具有内部类的特性,所有,从狭义上讲,它不是内部类。Static Nested Class与普通类在运行时的行为和功能上没有什么区别,只是在编程引用时的语法上有一些差别,它可以定义成public、protected、默认的、private等多种类型,而普通类只能定义成public和默认的这两种类型。在外面引用Static Nested Class类的名称为“外部类名.内部类名”。在外面不需要创建外部类的实例对象,就可以直接创建Static Nested Class,例如,假设Inner是定义在Outer类中的Static Nested Class,那么可以使用如下语句创建Inner类:

Outer.Inner inner = new Outer.Inner();

    由于static Nested Class不依赖于外部类的实例对象,所以,static Nested Class能访问外部类的非static成员变量。当在外部类中访问Static Nested Class时,可以直接使用Static Nested Class的名字,而不需要加上外部类的名字了,在Static Nested Class中也可以直接引用外部类的static的成员变量,不需要加上外部类的名字。

    在静态方法中定义的内部类也是Static Nested Class,这时候不能在类前面加static关键字,静态方法中的Static Nested Class与普通方法中的内部类的应用方式很相似,它除了可以直接访问外部类中的static的成员变量,还可以访问静态方法中的局部变量,但是,该局部变量前必须加final修饰符。

    备注:首先根据你的印象说出你对内部类的总体方面的特点:例如,在两个地方可以定义,可以访问外部类的成员变量,不能定义静态成员,这是大的特点。然后再说一些细节方面的知识,例如,几种定义方式的语法区别,静态内部类,以及匿名内部类。

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

    完全可以。如果不是静态内部类,那没有什么限制!

    如果你把静态嵌套类当作内部类的一种特例,那在这种情况下不可以访问外部类的普通成员变量,而只能访问外部类中的静态成员,例如,下面的代码:

class Outer
{
   static int x;
   static class Inner
   {
         void test()
         {
               syso(x);
         }
   }
}

    答题时,也要能察言观色,揣摩提问者的心思,显然人家希望你说的是静态内部类不能访问外部类的成员,但你一上来就顶牛,这不好,要先顺着人家,让人家满意,然后再说特殊情况,让人家吃惊。

Java面试宝典基础部分

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

    可以继承其他类或实现其他接口。不仅是可以,而是必须!

    30、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

    这属于脑筋急转弯的题目,在一个qq群有个网友正好问过这个问题,我觉得挺有趣,就研究了一下,没想到今天还被你面到了,哈哈。

    在test方法中,直接调用getClass().getName()方法,返回的是Test类名

    由于getClass()在Object类中定义成了final,子类不能覆盖该方法,所以,在

     test方法中调用getClass().getName()方法,其实就是在调用从父类继承的getClass()方法,等效于调用super.getClass().getName()方法,所以,super.getClass().getName()方法返回的也应该是Test。

如果想得到父类的名称,应该用如下代码:

 getClass().getSuperClass().getName();
本文来自IT学习资源网,若有错误烦请指正,谢谢!转载请注明出处。https://www.itziy.cn/20231122/1291.html

作者: Bunge

这个人很懒,所以啥也没有! 只望各位要保持学习的热情,认定的事情,一定要尽力做到哦!
广告位

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

联系我们

联系我们

1751282.........

在线咨询: QQ交谈

邮箱: 1370084491@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部