整理一些常见的java及android面试题(1)

来源:互联网 发布:unity3d opencv 编辑:程序博客网 时间:2024/05/23 00:39

(1).抽象类和接口有什么区别?

1.abstract class  Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface

2.abstract class 中可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface中,只能够有静态的不能被修改的数据成员(也就是必须是static final的,不过在 interface中一般不定义数据成员),所有的成员方法都是abstract的。

3.abstract classinterface所反映出的设计理念不同。其实abstract class表示的是"is-a"关系,interface表示的是"like-a"关系。

4.实现抽象类和接口的类必须实现其中的所有方法。抽象类中可以有非抽象方法。接口中则不能有实现方法。

5.接口中定义的变量默认是public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值。

6.抽象类中的变量默认是 friendly 型,其值可以在子类中重新定义,也可以重新赋值。

7.接口中的方法默认都是 public,abstract 类型的。

(2).在java中怎样实现多线程?

extends Thread

implement Runnable

方法一:继承 Thread 类,覆盖方法 run(),我们在创建的 Thread 类的子类中重写 run() ,加入线程所要执行的代码即可。下面是一个例子:

public class MyThread extends Thread
  
{
   
int count= 1, number;
   
public MyThread(int num)
   
{
    
number = num;
    
System.out.println
    ("创建线程
 " + number);
   
}
   
public void run() {
    
while(true) {
     
System.out.println
      ("线程 " + number + ":计数
 " + count);
     
if(++count== 6) return;
    
}
  
}
  
public static void main(String args[])
  
{
   for(int i = 0;i 
 5; i++) new MyThread(i+1).start();
  
}
 
}


这种方法简单明了,符合大家的习惯,但是,它也有一个很大的缺点,那就是如果我们的类已经从一个类继承(如小程序必须继承自 Applet 类),则无法再继承 Thread 类,这时如果我们又不想建立一个新的类,应该怎么办呢?
我们不妨来探索一种新的方法:我们不创建Thread类的子类,而是直接使用它,那么我们只能将我们的方法作为参数传递给Thread 类的实例,有点类似回调函数。但是 Java 没有指针,我们只能传递一个包含这个方法的类的实例。

  那么如何限制这个类必须包含这一方法呢?当然是使用接口!(虽然抽象类也可满足,但是需要继承,而我们之所以要采用这种新方法,不就是为了避免继承带来的限制吗?)

  Java 提供了接口 java.lang.Runnable 来支持这种方法。
方法二:实现 Runnable 接口

  Runnable接口只有一个方法run(),我们声明自己的类实现Runnable接口并提供这一方法,将我们的线程代码写入其中,就完成了这一部分的任务。但是Runnable接口并没有任何对线程的支持,我们还必须创建Thread类的实例,这一点通过Thread类的构造函数 public Thread(Runnable target);来实现。下面是一个例子:

  public class MyThread implements Runnable
  
{
   
int count= 1, number;
   
public MyThread(int num)
   
{
    
number = num;
    System.out.println("创建线程
 " + number);
   
}
   
public void run()
   
{
    
while(true)
    
{
     
System.out.println
     ("线程 " + number + ":计数
 " + count);
     
if(++count== 6) return;
    
}
   
}
   
public static void main(String args[])
   
{
    for(int i = 0; i 
 5;i++) new Thread(new MyThread(i+1)).start();
   
}
  
}

严格地说,创建Thread子类的实例也是可行的,但是必须注意的是,该子类必须没有覆盖 Thread 类的 run 方法,否则该线程执行的将是子类的 run 方法,而不是我们用以实现Runnable 接口的类的 run 方法,对此大家不妨试验一下。

  使用 Runnable 接口来实现多线程使得我们能够在一个类中包容所有的代码,有利于封装,它的缺点在于,我们只能使用一套代码,若想创建多个线程并使各个线程执行不同的代码,则仍必须额外创建类,如果这样的话,在大多数情况下也许还不如直接用多个类分别继承 Thread 来得紧凑。

(3).线程的四种状态

1. 新状态:线程已被创建但尚未执行(start() 尚未被调用)。

 2. 可执行状态:线程可以执行,虽然不一定正在执行。CPU 时间随时可能被分配给该线程,从而使得它执行。

 3. 死亡状态:正常情况下 run() 返回使得线程死亡。调用 stop() destroy() 亦有同样效果,但是不被推荐,前者会产生异常,后者是强制终止,不会释放锁。

4. 阻塞状态:线程不会被分配 CPU 时间,无法执行。

(4).线程的优先级

线程的优先级代表该线程的重要程度,当有多个线程同时处于可执行状态并等待获得 CPU 时间时,线程调度系统根据各个线程的优先级来决定给谁分配 CPU 时间,优先级高的线程有更大的机会获得 CPU 时间,优先级低的线程也不是没有机会,只是机会要小一些罢了。

  你可以调用 Thread 类的方法 getPriority()  setPriority()来存取线程的优先级,线程的优先级界于1(MIN_PRIORITY)10(MAX_PRIORITY)之间,缺省是5(NORM_PRIORITY)

(5)请说一下finalfinallyfinalize的区别?

final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。

finally是异常处理语句结构的一部分,表示总是执行。

finalizeObject类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。

   在Java中一个类被声明为final类型,表示了什么意思?

答:如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为abstract的,又被声明为final的。(扩展:将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载。)

(6) Error 与 Exception 有什么区别?

答:Error(错误)表示系统级的错误和程序不必处理的异常,是java运行环境中的内部错误或者硬件问题,比如,内存资源不足等,对于这种错误,程序基本无能为力,除了退出运行外别无选择。Exception(违例或异常)表示需要捕捉或者需要程序进行处理的异常,它处理的是因为程序设计的瑕疵而引起的问题或者外在的输入等引起的一般性问题,是程序必须处理的

(7)Overload 和 Override 的区别。 Overloaded 的方法是否可以改变返回值的类型?

答:Overload表示重载,Override表示覆盖或重写。重载(Overload)表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同)。重写(Override)表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这是面向对象编程的多态性的一种表现。

            如果几个Overloaded的方法的参数列表不一样,它们的返回值类型当然也可以不一样。如果两个方法的参数列表完全一样,通过让它们的返回值不同来实现重载Overload是不行的。

(8)接口是否可以继承接口?抽象类是否可以实现(implements)接口?抽象类是否可以继承实体类(concreteclass)?

答:接口不可以继承接口,接口之间有类似继承的关系,但是严格说成是继承是不对的,因为接口是要被实现而不是被继承的。抽象类可实现接口。抽象类可以继承实体类,但是要求实体类必须有明确的构造函数。

(9)构造器Constructor是否可被override?

答:构造器Constructor不能被继承,因此不能重写Override,但可以被重载Overload。

(10)是否可以继承String类?

答:string类是final类故不可以继承。

(11)try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?

答:会执行,在return前执行。

(12)swtich是否能作用在byte上,是否能作用在long上,是否能作用在string上?

答:switch(expr1)中,expr1是一个整数表达式。因此传递给 switch 和 case 语句的参数应该是 int、 short、 char 或者 byte。但是long,string 都不能作用于swtich。
(13)char型变量中能不能存储一个中文汉字?为什么?

答:可以。JAVA默认的编码是UNICODE.不是ASCII的char。

(14)String与StringBuffer的区别?

答:String:是对象不是原始类型,为不可变对象,一旦被创建,就不能修改它的值;对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去;String是final类,即不能被继承。StringBuffer:是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象,它只能通过构造函数来建立:StringBuffer sb = new StringBuffer();不能通过付值符号对他进行付值:sb = "welcome to here!";对象被建立以后,在内存中就会分配内存空间,并初始保存一个null;向StringBuffer中付值的时候可以通过它的append方法。字符串连接操作中StringBuffer的效率要比String高:

(15)throw和throws有什么不同?

答:throws是用来声明一个方法可能抛出的所有异常信息;throw则是指抛出的一个具体的异常类型。通常在一个方法(类)的声明处通过throws声明方法(类)可能抛出的异常信息,而在方法(类)内部通过throw声明一个具体的异常信息。.对异常处理方式不同.throws对异常不处理,谁调用谁处理,throws的Exception的取值范围要大于方法内部异常的最大范围,而cathch的范围又要大于throws的Exception的范围;throw 主动抛出自定义异常类对象;throws抛出的是类,throw抛出的是对象。

(16)“deprecatedAPI”,是什么意思?

答:“deprecated API”表示JAVA开发中不赞成使用的应用程序接口,是JAVA早期的应用程序接口版本,不赞成使用。

(17)什么是内部类,内部类在什么情况下应用?

答:可以将一个类的定义置入另一个类中定义,这就叫做“内部类”。

以下情况下应用内部类:·只用到类的一个实例。  

·类在定义后马上用到。 

·类非常小(SUN推荐是在4行代码以下)  

·给类命名并不会导致你的代码更容易被理解。
(扩展:)在使用匿名内部类时,要记住以下几个原则:

·匿名内部类不能有构造方法。  

·匿名内部类不能定义任何静态成员、方法和类。  

·匿名内部类不能是public,protected,private,static。  

·只能创建匿名内部类的一个实例。

(18)什么是静态自由块,主要有什么作用?

答:声明为static属性的代码块就叫做静态自由块。其主要作用:static代码快可以不用创建对象来调用,可以直接用类名+方法名来调用.