Java 面试知识点1

  • **final,finally和finalize()三者的区别:

  • final是关键字:

final可以修饰类,方法,变量(成员变量,局部变量)
修饰类—>该类是最终类不能被继承;所以一个类不能既被声明为是abstract,又被声明为final。
修饰方法—>该方法不能被重写;
修饰变量—>该变量变成常量且只能被赋值(在构造方法执行完之前完成赋值)一次。

常量:变量被final修饰之后就变为常量,常量只能被赋值一次且在以后的引用中只能读取,而不可修改。 常量又分为普通常量和静态常量。
被final修饰之后的普通常量前面还有static修饰就叫做静态常量。
普通常量和静态常量的区别:静态常量是必须在声明的时候就进行赋值,而普通常量在定义的时候可以不赋值,但必须在构造方法执行完之前进行赋值。
注意: 常量的命名规范:字母全部要大写,如果这个名字是由多个单词组成,在单词之间用_隔开。

  • finally也是关键字:
    用在异常中,提供 finally 块用来释放资源,无论是否有异常产生,finally中的代码都会最终都会被执行(如果有的话)。

  • finalize()是Object类的方法:
    Java 技术允许使用 finalize() 方法在垃圾回收器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾回收器在确定这个对象没不存在更多引用的时候调用的,调用此方法垃圾回收器会进行垃圾回收,但是不保证被及时回收。当确定这个对象不存在引用的时候可以手动通过System.gc().finalize()调用该方法及时进行垃圾回收。

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

    没有名字的内部类叫做匿名内部类。因为没有名字,所以你无法在别的地方使用这个类(实例化,调用它的静态方法之类等),通常用来简化代码编写。
    它不能去extends(继承) 其它类,但是一个内部类可以作为一个接口,由另一个内部类来进行实现。
    关于内部类以及匿名内部类的详情可以参考博客地址:http://blog.csdn.net/yangshuxian1/article/details/51443079

  • Static Nested Class 和 Inner Class的不同。
    Static Nested Class—>静态嵌套类(一般是C++的说法);Inner Class—>内部类(一般是JAVA的说法)。
    C++嵌套类和Java内部类最大的不同就在于是否有指向外部的引用上。
    Static Nested Class (静态嵌套类)是Inner Class(内部类)的一种,因为是静态的,所以嵌套类要创建对象时,不需要外部类的对象,可以用Outer.new Inner()来创建对象;静态嵌套类不能访问非静态外部类成员。

  • 谈谈&和&&的相同点和区别。

    1)相同点:
    &和&&都可以用作布尔逻辑与的运算符,表示逻辑与(and)—>当运算符两边的表达式的结果都为true时,整个运算结果才为true;否则,只要有一方为false,则结果为false。
    2)区别:
    但&&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式。
    eg.对于if(str != null && !str.equals(“”))表达式,当str为null时,后面的表达式不会执行,所以不会出现NullPointerException; 如果将&&改为&,则会抛出NullPointerException异常。
    还有eg. If(x==33 & ++y>0) 表达式中y会增长,而If(x==33 && ++y>0)表达式中y不会增长。
    &还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位。
    eg. 0x31 & 0x0f的结果为0x01。

  • 再谈谈或操作(|和||)的相同点和区别:
    |- 普通或(|):表示所有的判断条件都要执行,不管前面是否满足;
    |- 短路或(||):如果前面的条件已经是true了,那么后面无论如何判断都是true,就不用判断了;
    • 当然在开发之中考虑到程序的执行效率和性能肯定使用短路与(&&)和短路或(||)。

  • HashMap和Hashtable的相同点和区别。
    两者都属于Map接口的类,实现了将惟一键映射到特定的值上。
    Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。
    HashMap是不同步的(线程安全性低,但效率高), 而Hashtable 是同步的(Synchronize)(所以线程安全性高,但效率低)—>在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步(Collections.synchronizedMap)。
    HashMap允许将null作为一个entry的key或者value,而Hashtable不允许将null作为一个entry的key或者value;
    HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。
    Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。

  • String是基本类型吗?基本类型有哪些?
    基本数据类型:byte、short、int、long、float、double、boolean和char。
    除了基本类型(primitive type)和枚举类型(enumerationtype),剩下的都是引用类型(reference type),所以String不是最基本的数据类型而是引用数据类型。

  • 分析出以下程序的打印结果:

public class Person {
    public static String print(String str){
        str = "1234";
        System.out.println(str) ;---->打印出:1234; 
        return str;
    }
    public static void main(String[] args){
        String str  = "abcd";
        print(str);     ---->打印出:abcd;
        System.out.println(str);
    }
} 

函数的参数分为形参和实参两种。 形参出现在函数定义中,在整个函数体内都可以使用;实参出现在主调函数中;形参和实参的功能都是数据传送。
发生函数调用时,主调函数把实参的值传送给被调函数的形参从而实现主调函数向被调函数的数据传送。
实参:只传递数值,在过程(函数)中对之所进行的改动,不会造成原始变量值的改变;与之相对的形参:地址参数,传的是变量地址,所以在函数中的任何改动都会影响到主函数的实际参数。

  • 面向对象的基本特征有那些?

1) 抽象(abstract)
就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处,忽略与当前主题和目标无关的方面,将注意力集中在与当前目标有关的方面。抽象包括行为抽象和状态抽象两个方面。例如,定义一个Person类,如下:

classPerson{
       String name;
       int age;
}

人本来是很复杂的事物,有很多方面,但因为当前系统只需要了解人的姓名和年龄,所以上面定义的类中只包含姓名和年龄这两个属性,这就是一种抽象,使用抽象可以避免考虑一些与目标无关的细节。
抽象包括两个方面, 一是过程抽象,二是数据抽象。

> java中用abstract表示抽象,可以修饰类、方法;

   java中没有方法体(即没有{})的方法就是抽象方法, 就用abstract修饰;
   有抽象方法的类为抽象类,用abstract修饰;
   抽象类不一定有抽象方法;
   抽象类不能实例化,但是有构造方法à构造方法在这里仅仅初始化数据
   如何才能访问抽象类的成员?à通过多态的特征让子类进行实例化
   抽象类的子类à要么也是抽象类,要么重写抽象类中的所有抽象方法

> 抽象类的成员的特点:

1.成员变量可以是变量也可以是常量
2.成员方法可以是抽象也可以非抽象
3.有构造方法, 但是不能实例化;

>abstract关键字: abstract是一个修饰符。只可以修饰类,方法;

abstract不能和以下关键字共存:private、final、static; 当我们多个类存在相同的功能,但是功能的主体不同,这时我进行向上抽取,只抽取功能的定义不抽取功能的主体。

  • >抽象类的特点:

    1.java中没有方法体的方法就是抽象方法
    2.抽象方法一定要在抽象类中;有抽象方法的类为抽象类
    3.抽象类和抽象方法必须要被abstract关键字修饰
    4.抽象类不一定有抽象方法
    5.抽象的类是不能被创建对象,因为调用抽象的方法没意义
    6.但是抽象类有构造方法—>构造方法在这里仅仅初始化数据
    7.抽象类的中方法要被使用,必须由子类重写抽象类中的方法,然后创建子类对象来调用
    8.成员变量可以是变量也可以是常量
    9.抽象类中可以定义非抽象的方法,有时我们需要此类不能被new关键字创建对象时,可以用abstract将此类变成抽象类。
    10.子类如果只重写一部分的抽象方法,那么该子类还是一个抽象类,如果抽象类的方法要被使用,子类必须重写抽象类中的所有方法。


2) 封装(Encapsulation)

封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的“高内聚、低耦合”,防止程序相互依赖性而带来的变动影响。
面向对象的封装就是把描述一个对象的属性和行为的代码封装在一个“模块”中,也就是一个类中,属性用变量定义,行为用方法进行定义,方法可以直接访问同一个对象中的属性。
通常情况下,只要让变量和访问这个变量的方法放在一起,将一个类中的成员变量全部定义成私有的,只有这个类自己的方法才可以访问到这些成员变量,这就基本上实现对象的封装。
把握一个原则:把对同一事物进行操作的方法和相关的方法放在同一个类中,把方法和它操作的数据放在同一个类中。

  • > 封装指的是:

       1.先将对象的状态信息(属性)和行为(方法)捆绑为一个逻辑单元的机制。
       2.隐藏对象状态信息(属性)和行为(实现细节);
       3.仅对外提供公共访问方式
       对应代码步骤就是:
       à-1.将成员变量私有化(用private修饰);
       à-2.向外提供(public)公共的set方法(setter)和get方法(getter);
       *好处:*
       1.有利于保证数据的完整性;
       2.提高了代码安全性;
       3.提高代码的复用性;
       4.增强代码的可维护性,便于修改;
       5.有助于建立个系统之间的松耦合关系,提高系统独立性;
    
  • 松耦合关系:

    强内聚—模块的功能尽量在模块内部独立完成,不让外面干预;
    弱耦合—提供给外部尽量少的方法调用;
    代码的最高境界就是强内聚,弱耦合;

3) 继承(extends)
在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并可以加入若干新的内容,或修改原来的方法使之更适合特殊的需要,这就是继承。
继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提高了软件的可重用性和可扩展性。

  • 继承(extends):

Java中用关键字extends实现继承。 语法格式:class 子类 extends 父类; 父类又叫做基类,超类;子类又叫派生类.
继承之后,子类可以共享父类数据,这个过程就是泛化的过程。
注意: java类与类之间只支持单继承,不支持多继承,但是可以多重继承; 私有( private) 成员(成员方法和成员变量)不能被继承; 构造方法不能被继承,但是子类构造会默认调用父类的无参构造; 怎么调用?à通过super()调用。
记住:子类构造可执行代码的第一行默认有super();
为什么会有super()?à因为子类需要使用父类的数据,而父类的数据需要通过父类构造初始化。

*继承的好处:*

1.提高了代码的复用性;
2.提高了代码的维护性;
3.让类与类之间产生了关系,是实现多态的前提;

*继承的弊端:*

1.打破了代码的封装性;
2.增强了代码的耦合性;

注意:不能为了部分功能而继承. 那到底什么时候使用继承呢?— 继承中类之间体现的是: ”…is a…”的关系。

  • super()方法:

继承关系的初始化: 分层初始化—>先初始化父类, 再初始化子类;
java中最基本的单元是类, 初始化就是对类的成员变量初始化;

1.默认初始化:在程序里,数据初始化也可能在没有由明确的语法来实现的情况下进行。 例: 如果一个静态变量在没有初始化(即未指定初值)的情况下被声明,则:
对于原生数据类型:以对应类型的零值进行初始化;
对于类中的静态对象:由其默认的构造函数来进行初始化。
2.显式初始化:
3.构造初始化:

4) 多态(Polymorphism)

多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。
多态性增强了软件的灵活性和扩展性。

  • 多态(Polymorphism):
    概述:某一个事物, 在不同时刻表现出来的不同状态。
    如何实现?

    1.有继承或者实现关系(二者满足其一即可)
    2.有方法的重写( 非必须)
    3.有父类引用指向子类对象成员访问特点:

    规律:

    成员变量: 编译看左边, 运行看左边
    成员方法: 编译看左边, 运行看右边
    静态方法: 编译看左边, 运行看左边

好处:

1.提高了代码的维护性(由继承保证)
2.提高了代码的扩展性(由多态保证)

弊端:

不能访问子类特有的成员。

如何访问?—->使用多态中的转型(向下转型)访问:
1.对象的向上转型 子类转成父类 默认进行 父类引用指向子类对象

         Fu fu = (fu)new Zi();

2.对象的向下转型 父类转成子类 强制进行

              Zi zi = (Zi)fu;

instanceof:

关键字instanceof 是用来测试左边的对象是否是右边类的实例 ;
如果是返回true;不是则返回false

  • 重写和重载的区别?(重点),什麽时候用重写,重载?

方法的重载(overload):
方法重载是指在一个类中定义多个同名的方法,但要求个方法具有不同的参数列表(包括参数的类型和参数的个数。

调用重载方法时,Java编译器能通过检查调用的方法的参数类型和个数选择一个恰当的方法。
方法重载通常用于创建完成一组任务相似但参数的类型或参数的个数不同的方法。

方法的重写(override):

在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。
但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称 方法覆盖。
若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。
如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。


  • > 关于方法重写的一些特性:

1.发生方法重写的两个方法返回值、方法名、参数列表必须完全一致(子类重写父类的方法)
2.私有的方法不能够被重写;静态方法复写也必须是静态方法;
3.子类方法的访问级别不能低于父类相应方法的访问级别(子类访问级别不能低于父类访问级别)
4.子类抛出的异常下不能超过父类相应方法抛出的异常(子类异常不能大于父类异常)
5.构造方法不能够被重写—因为和第1条矛盾;
6.根据2,3条是不是能确定第一条,子类方法的返回值必须是父类方法返回值的子类。

猜你喜欢

转载自blog.csdn.net/yuki5233/article/details/70105331