JavaSE_3_面向对象

1、wait方法底层原理

wait是object中的方法,可以暂停线程,会释放对象锁,不像sleep方法,线程休眠期依然持有锁,通过调用notify或notifyAll方法唤醒线程。

lock.wait()方法最终通过ObjectMonitor的wait()方法实现:

  1. 将当前线程封装成ObjectWaiter对象node;
  2. 通过ObjectMonitor的AddWaiter方法将node添加到WaitSet列表中;
  3. 通过ObjectMonitor的exit方法释放当前的ObjectMonitor对象,这样其它竞争线程就可以获取该ObjectMonitor对象。

ObjectMonitor对象中有两个队列:WaitSet和EntryList:

  • WaitSet:处于wait状态的线程,会被加入到WaitSet;
  • EntryList:处于竞争锁状态的线程,会被加入到EntryList。

2、Java有哪些特性,举个多态的例子。

封装、继承、多态;

举例:方法重载、父类型引用子类对象。

3、String为啥不可变?

因为String类源码定义的是一个private final修饰的名为value的字符数组;被final修饰即为常量,不可变;被private修饰且没有set函数,不可被修改。

4、类和对象的区别

类是一个抽象的概念,类只是为所有的对象定义了抽象的属性与方法;对象是类的一个具体;

类是一个静态的概念,类本身不携带任何数据,当没有为类创建任何对象时,类本身不存在于内存空间中;对象是一个动态的概念,每一个对象都存在着属于自己的独特的属性和方法;

总结:类是对象的模板,对象是类的实例。

5、请列举你所知道的Object类的方法。

  1. clone():创建并返回此对象的一个副本;
  2. equals():检查其他某个对象是否与此对象“相等”;
  3. getClass():返回此Object的运行时类;
  4. hashCode():返回该对象的哈希码值;
  5. notify():随机唤醒一个等待线程;
  6. notifyAll():唤醒所有等待线程;
  7. toString():返回该对象的字符串表示;
  8. wait():在其他线程调用此对象的notify()方法或notifyAll()方法前,导致当前线程等待。

6、重载和重写的区别?相同参数不同返回值能重载吗?

重写:一个类继承一个父类时,将从父类那继承来的方法,进行重新写过;
重载:多个同名方法,名称相同,但是参数不同,可以通过参数来识别调用的是哪一个方法。
相同参数不同返回值不可以重载。

7、”static”关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法?

static表示静态的意思,可用于修饰成员变量和成员函数,被static修饰的成员函数只能访问静态成员,不能访问非静态成员,静态是随着类的加载而加载的,因此可以直接用类进行访问。

无法重写被private修饰的方法,因为被private修饰的父类方法在子类中是不可见的;

可以重写被static修饰的方法,但是运行时调用的是父类的方法,因为虚拟机把子类重写的static方法隐藏了(实例方法被覆盖,静态方法被隐藏)。

8、String能继承吗?

String不能被继承,因为String类是被final修饰的,被final修饰的类是不能被继承的。

9、StringBuffer和StringBuilder有什么区别,底层实现上呢?

StringBuilder运行速度比StringBuffer快;

StringBuilder不是线程安全的,StringBuffer是线程安全的。

在底层实现上,StringBuilder和StringBuffer都继承自AbstractStringBuilder类,但是StringBuffer重写AbstractStringBuilder方法的时候使用了同步块synchronized,而StringBuilder没有使用。

10、类加载机制,双亲委派模型,好处是什么?

JVM第一次使用到这个类时需要对这个类的信息进行加载,一个类只会加载一次,之后这个类的信息放在堆空间,静态属性放在方法区;

JVM类加载器从上到下一共分为三类 :

  1. 启动类加载器(Bootstrap ClassLoader):负责加载JAVA_HOME\lib目录中的,或通过-Xbootclasspath参数指定路径中的,且被虚拟机认可的类;
  2. 扩展类加载器(Extension ClassLoader):负责加载JAVA_HOME\lib\ext目录中的,或通过java.ext.dirs系统变量指定路径中的类库;
  3. 应用程序类加载器(Application ClassLoader):负责加载用户路径上的类库。

JVM通过双亲委派模型进行类的加载,采用双亲委派的一个好处就是Java类随着它的类加载器一起具备了一种带有优先级的层次关系。比如加载位于rt.jar包中的类java.lang.Object,不管是哪个加载器加载这个类,最终都是委托给顶层的启动类加载器进行加载,这样就保证了使用不同的类加载器最终得到的都是同样一个Object对象。

11、静态变量存在哪?

静态变量存储在方法区中。(类信息、常量和静态变量都存储在方法区中)

12、讲讲什么是泛型?

泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型);比如:ArrayList<E> E就是泛型,这种不确定的数据类型需要在使用这个类的时候才能够确定出来。

13、解释extends 和super 泛型限定符-上界不存下界不取

上界用extends关键字声明,表示参数化的类型可能是所指定的类型,或者是此类型的子类,add方法受阻,可以从一个数据类型里获取数据;

下界用super关键字声明,表示参数化的类型可能是所指定的类型,或者是此类型的父类型,get方法受阻,可以把对象写入一个数据结构里。

14、是否可以在static环境中访问非static变量?

不可以,因为静态成员属于类,随着类的加载而加载到静态方法区内存,当类加载时,此时不一定有实例创建,没有实例,就不可以访问非静态的成员。

15、谈谈如何通过反射创建对象?

//获取String所对应的Class对象
Class c = String.class;
//获取String类带一个String参数的构造器
Constructor constructor = c.getConstructor(String.class);
//根据构造器创建实例
Object obj = constructor.newInstance("23333");

16、Java支持多继承么?

Java中类不支持多继承,只支持单继承;但是java中接口支持多继承,即一个子接口可以有多个父接口。(接口的作用是用来扩展对象的功能,一个子接口继承多个父接口,说明子接口扩展了多个功能,当类实现接口时,类就扩展了相应的功能)

17、接口和抽象类的区别是什么?

从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为规范。

18、Comparable和Comparator接口是干什么的?列出它们的区别。

Comparable和Comparator可以用来实现集合中元素的比较和排序:

  • Comparable是在集合内部实现的排序:类实现Comparable接口,然后重写了compareTo方法,这个类就拥有了内部比较器;
  • Comparator是在集合外部实现的排序:新定义一个类,类名随意,让这个类实现Comparator接口,重写compare方法,这个类就实现了外部比较器。

19、面向对象的特征有哪些方面

面向对象的四大特征:封装,继承,多态,抽象。

20、final, finally, finalize的区别。

final:如果一个类被声明为final,则该类不能被继承;如果一个方法被声明为final,则该方法不能在子类中被重写;如果一个变量被声明为final,则该变量的值不能被改变,即为常量;

finally:通常放在try…catch…的后面构造,无论程序正常执行还是发生异常,finally块中的代码都会执行,可以将释放外部资源的代码写在finally块中;

finalize:Object类中的方法,finalize()方法会在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。

21、Overload和Override的区别。Overload的方法能否根据返回类型进行区分?

override(重写)(运行时多态)

  • 方法名、参数、返回值相同;
  • 子类方法不能缩小父类方法的访问权限;
  • 子类方法不能抛出比父类方法更多的异常;
  • 发生在子类和父类中;
  • 方法被定义为final不能被重写。

overload(重载)(编译时多态)

  • 参数类型、个数、顺序至少有一个不相同;
  • 不能重载只有返回值不同的方法名;
  • 发生在同一个方法中。

Overload的方法不能根据返回类型进行区分。

22、abstract class和interface有什么区别?

  1. interface需要实现,要用implements,而abstract class需要继承,要用extends;
  2. 一个类可以实现多个interface,但一个类只能继承一个abstract class;
  3. interface强调特定功能的实现,而abstract class强调所属关系;
  4. interface中的每一个方法都是抽象方法,只是声明,没有方法体,实现类必须要实现,而abstract class的子类可以有选择地实现,这个选择有两点含义:
  • abstract class中并非所有的方法都是抽象的,只有那些被abstract修饰的方法才是抽象的,子类必须实现,那些没有被abstract修饰的方法,在abstrct class中必须定义方法体;
  • abstract class的子类在继承它时,对非抽象方法既可以直接继承,也可以覆盖,而对抽象方法,可以选择实现,也可以通过再次声明为抽象的方式,无需实现,留给其子类来实现,但此类必须也声明为抽象类。

23、Static Nested Class 和 Inner Class的不同

静态内部类(嵌套类):要创建嵌套类的对象,不需要其外围类的对象;嵌套类不能访问外部类的非静态变量和方法;

内部类(Inner Class):定义在类中的类,它的创建依赖一个外部类对象作为宿主,内部类必须寄生在外部类对象中才能创建实例。

24、当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

值传递。Java编程语言中只有值传递,没有引用传递,当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象引用的一个副本,指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。

25、Java的接口和C++的虚类的相同和不同处。

C++虚类相当于java中的抽象类,与Java接口的不同之处是:

  • 一个子类只能继承一个抽象类(虚类),但能实现多个接口;
  • 一个抽象类可以有构造方法,接口没有构造方法;
  • 一个抽象类中的方法不一定是抽象方法,即其中的方法可以有实现(有方法体),接口中的方法都是抽象方法,不能有方法体,只有声明;
  • 一个抽象类可以是public、private、protected、default,接口只能是public;
  • 一个抽象类中的方法可以是public、private、protected、default,接口中的方法只能是public和default。

相同之处:

  • 都不能实例化。

26、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗

Java使用面向对象的方式来处理异常,它把程序中发生的每个异常都分别封装成一个对象来表示,该对象中包含异常的信息,而throws,throw,try,catch,finally就是Java中用对异常进行处理的五个关键字。

throws:声明一个方法可能抛出的所有异常信息,throws只声明异常但不处理,而是将异常往上传,谁调用该方法就交给谁处理;

throw:抛出异常,用在方法体内;

try:指定可能发生异常的语句,从而进行异常的处理;

catch:捕获相应的异常,执行里面的语句;

finally:不论是否有异常都会执行里面的语句。

try块中可以抛出异常。

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

如果不是静态内部类,没有什么限制,可以访问外部类中的成员包括私有成员;如果是静态内部类,则只能访问外部类中的静态成员,不能访问其非静态成员。

28、两个对象值相同(x.equals(y) == true),但却可有不同的hash code说法是否正确?

首先,这句话应该是错误的,因为java语言要求了:

  • 两个对象equals比较相同,它们的hash code一定相同;
  • 两个对象equals比较不同,它们的hash code不一定不同;
  • 两个对象的hash code不同,它们equals比较一定不同;
  • 两个对象的hash code相同,它们equals比较不一定相同。

其次,如果重写了equals而没有重写hash code的话,可以使得上诉说法正确,但是这样违背了java语言的规定。

29、如何通过反射获取和设置对象私有字段的值?

    /***
     * 获取私有字段的值
     * 
     */
    public static Object getValue(Object instance, String fieldName)
            throws IllegalAccessException, NoSuchFieldException {

        Field field = instance.getClass().getDeclaredField(fieldName);
        field.setAccessible(true); // 参数值为true,禁止访问控制检查
        return field.get(instance);
    }

    /***
     * 设置私有字段的值
     * 
     */
    public static void setValue(Object instance, String fileName, Object value)
            throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {

        Field field = instance.getClass().getDeclaredField(fileName);
        field.setAccessible(true);
        field.set(instance, value);
    }

30、谈一下面向对象的"六原则一法则"。

  1. 单一职责原则:一个类只做它该做的事情。(单一职责原则想表达的就是"高内聚",写代码最终极的原则只有六个字"高内聚、低耦合",所谓的高内聚就是一个代码模块只完成一项功能,在面向对象中,如果只让一个类完成它该做的事,而不涉及与它无关的领域就是践行了高内聚的原则,这个类就只有单一职责);
  2. 开闭原则:软件实体应当对扩展开放,对修改关闭。(在理想的状态下,当我们需要为一个软件系统增加新功能时,只需要从原来的系统派生出一些新类就可以,不需要修改原来的任何一行代码。要做到开闭有两个要点:①抽象是关键,一个系统中如果没有抽象类或接口,该系统就没有扩展点;②封装可变性,将系统中的各种可变因素封装到一个继承结构中,如果多个可变因素混杂在一起,系统将变得复杂而混乱);
  3. 依赖倒转原则:面向接口编程。(该原则说得直白和具体一些就是声明方法的参数类型、方法的返回类型、变量的引用类型时,尽可能使用抽象类型而不用具体类型,因为抽象类型可以被它的任何一个子类型所替代);
  4. 里氏替换原则:任何时候都可以用子类型替换掉父类型。(简单的说就是能用父类型的地方就一定能使用子类型。里氏替换原则可以检查继承关系是否合理,如果一个继承关系违背了里氏替换原则,那么这个继承关系一定是错误的,需要对代码进行重构);
  5. 接口隔离原则:接口要小而专,绝不能大而全。(臃肿的接口是对接口的污染,接口表示能力,一个接口只应该描述一种能力,接口也应该是高度内聚的);
  6. 合成聚合复用原则:优先使用聚合或合成关系复用代码;
  7. 迪米特法则:迪米特法则又叫最少知识原则,一个对象应当对其他对象有尽可能少的了解。(迪米特法则简单的说就是如何做到"低耦合")。

31、请问Query接口的list方法和iterate方法有什么区别?

list方法:

  • 在Hibernate中,query.list()方法是通过一条Select SQL语句获取所有的记录,并将其读出,填入到POJO中返回,所以list()方法返回的每个对象都是完整的(对象中的每个属性都被表中的字段填充上了),所以返回的每个对象都是原本的对象;
  • list()方法无法利用一级缓存和二级缓存(对缓存只写不读),它只能在开启查询缓存的前提下使用查询缓存。

iterator方法:

  • query.iterator()方法返回的对象中仅包含了主键值,只有当你对iterator中的对象进行操作时,Hibernate才会向数据库再次发送SQL语句来获取该对象的属性值,所以返回的对象是代理对象。list方法需要1条SQL语句,iterate可能需要N+1条。
  • iterator()方法可以充分利用缓存,可以对缓存读和写;返回对象的主键值时,hibernate首先会根据这个值在本地Cache内寻找对应的数据,如果没找到,再去数据库中检索;如果目标数据只读或者读取频繁,使用iterate()方法可以减少性能开销。

32、Java中,什么是构造函数?什么是构造函数重载?什么是复制构造函数?

当新对象被创建的时候,构造函数会被调用,每一个类都有构造函数,在程序员没有给类提供构造函数的情况下,Java编译器会为这个类创建一个默认的构造函数,构造函数的函数名和类名一致,没有返回值。

java中构造函数的重载和方法重载很相似;可以为一个类创建多个构造函数,每一个构造函数都必须有他唯一的参数列表。

java不支持C++中的复制构造函数,这个不同点是因为如果你不自己写复制构造方法的情况下,Java不会创建默认的复制构造方法。

posted @ 2019-04-02 15:33  刘牛奶  阅读(199)  评论(0编辑  收藏  举报