面试-面向对象

一、若对一个类不重写,它的equals()方法是如何比较的?

答:比较的是对象的地址。

二、请你解释hashcode()和equals()方法有什么联系?

答:①相等的对象必须具有相等的哈希码;

②如果两个对象的hashcode相同,它们并不一定相同。

三、请解释java中的概念,什么是构造函数?什么是构造函数重载?什么是复制构造函数?

答:当新对象被创建的时候,构造函数会被调用。每一个类都有构造函数。在程序员没有给来提供构造函数的情况下,java编译器会为这个类创建一个默认的构造函数。java中构造函数重载和方法重载很相似。可以为一个类创建多个构造函数。每一个构造函数必须有它自己唯一的参数列表。java不支持像c++中那样的复制构造函数,这个不同点是因为如果你不自己为写构造函数的情况下,java不会创建默认的复制构造函数。

四、请说明java中的方法覆盖和方法重载是什么意思?

答:java中的方法重载发生在同一个类里面两个或者是多个方法的方法名相同但是参数不同的情况。与此相对,方法覆盖是说子类重新定义了父类的方法。方法覆盖必须有相同的方法名,参数类型和返回类型。覆盖着可能不会限制它所覆盖的方法访问。

五、请说明Query接口的list方法和iterate方法有什么区别?

答:①list方法无法利用一级缓存和二级缓存(对缓存只读不写),它只能在开启查询缓存的前提下使用查询缓存;iterate()方法可以充分利用缓存,如果目标数据只读或者读取频繁,使用iterate()方法可以减少性能开销。

②list方法不会引起n+1查询问题,而iterate()方法可能会引起n+1查询问题。

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

答:可以通过类对象的getDeclareField()方法字段对象,然后再通过字段对象的setAccessible(true)将其设置为可以访问,接下来就可以通过get/set方法来获取/设置字段的值了。

七、请说明重载和重写的区别?重载的方法能够根据返回类型进行区分?

答:方法的重载和重写都是实现多态的方法,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态。重载发生在一个类中,同名的方法如果有不同的参数列表则视为重载;重写发生在子类与父类之间,重写要求子类被重写的方法与父类方法被重写的方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常。重载对返回类型没有特殊的要求。

八、请判断,两个对象值相同(x.equals(y)==true),但却可有不同的hashcode,该说法是否正确,为什么?

答:不对,如果两个对象x和y满足x.equals(y)==true,它们的哈希码应当相同。java对于equals方法和hashcode方法是这样规定的:

①如果两个对象相同(equals方法返回true),那么它们的hashcode值一定要相同。

②如果两个对象的hashcode相同,它们不一定相同。

当然,你未必要按照要求去做,但是如果你违背了上述原则就会发现在使用容器时,相同的对象可以在set集合中,同时增加新元素的效率会大大下降(对于使用哈希存储的系统,如果哈希码频繁的冲突将会造成存取性能急剧下降)。

九、请说明内部类可以引用其他包含类的成员吗?如果可以,有没有什么限制?

答:一个内部类对象可以访问创建它的外部类对象的内容,内部类如果不是static的,那么可以访问创建它的外部类对象的所有属性内部类。如果是static的,那么它只可以访问创建它的外部类的所有static属性,一般普通类只有public或者package的访问修饰,而内部类可以实现static,protected,private等访问修饰。当从外部类继承的时候,内部类是不会被覆盖的,它们是完全独立的实体,每个都在自己的命名空间内,如果从内部类中明确地继承,就可以覆盖原来内部类的方法。

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

答:java通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在java中,每个异常都是一个对象,他是throwable类或其他子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。java的异常处理是通过5个关键字来实现的:try、catch、throw、throws和finally。一般情况下使用try来执行一段程序,如果出现异常,系统会抛出(throws)一个异常,这时候就可以通过它的类型来捕获(catch)它,或最后(finally)由缺省处理器来处理。用try来指定一块预防所有”异常“的程序紧跟在try程序后面,应包含一个catch字句来指定把你想要捕捉的异常类型。

throw语句用来明确地抛出一个”异常“。

throws用来标明一个成员函数可能抛出的各种”异常“.

finally会确保一段代码不管发生什么异常都会被执行一段代码。

可以在一个成员函数调用的外面写一个try语句,在这个成员函数内部写另一个try语句保护其他代码。每当遇到一个try语句,异常的框架就放在堆栈上面,直所有的try语句都完成。如果下一级的try语句没有对某种异常进行处理,堆栈就会展开,直到遇到有处理这种异常的try语句。

十一、请判断当一个对象被当做参数传递给一个方法后,这个方法可以改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

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

十二、请你讲讲抽象类和接口的区别?

答:声明方法的存在而不去实现它的类被叫做抽象类,它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。

接口是抽象类额变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。

抽象类是最大限度的抽取之类共性,接口是规范类的开发。

十三、请说明fianl,finally,finalize的区别?

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

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

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

十四、请说明面向对象的特征有哪些方面?

答:①抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面:一是过程抽象;二是数据抽象。

②继承:继承是一种连接类的层次模型,并且允许和鼓励累的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类,而原始类称为新类的基类。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或者增加新的方法使之更适合特殊的需要。

③封装:封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。

④多态性:是指允许不同类的对象对同一消息作出响应。

十五、请说明Comparable和Comparator接口的作用以及它们的区别?

答:java提供了只包含一个compareTo()方法的Comparable接口。这个方法可以给两个对象排序。具体来说,它返回负数,0,正数来表明输入对象小于,等于,大于已经存在的对象。

java提供了包含compare()和equals()两个方法的comparator接口。compare()方法用来给两个输入参数排序,返回负数,0,正数标明第一个参数是小于,等于,大于第二个参数。equals()方法需要一个对象作为参数,它用来决定输入参数是否和comparator相等。只有当输入参数也是一个comparator并且输入参数和当前comparator的排序结果是相同的时候,这个方法才返回true.

十六、请说明java是否支持多继承?

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

十七、请你谈谈如何通过反射创建对象?

答:①通过类对象调用newInstance()方法。

例如:String.class.newInstance();

②通过类对象的getConstructor()或getDeclaredConstructor()方法获得构造器对象并调用其newInstance()方法创建对象。

例如:String.class.getConstructor(String.class).newInstance("hello");

十八、请你说明是否可以在static环境中访问非static变量?

答:static变量在java中是属于类的,他在所有的实例中的值是一样的。当类被java虚拟机载入的时候,会对static变量进行初始化。如果你的代码尝试不用实例来访问非static的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上。

十九、请你讲讲什么是泛型?

答:泛型,即”参数化类型“。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呐?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式,然后在使用/调用时传入具体的类型。

二十、请说明静态变量存在什么位置?

答:方法区。

二十一、请你谈谈StringBuffer和StringBuilder有什么区别,底层实现上呐?

答:StringBuffer线程安全,StringBuilder线程不安全,底层实现上的话,StringBuffer其实就是比StringBuilder多了Synchronized修饰符。

二十二、请说明String是否能被继承?

答:不能,char数组用fianl修饰的。

二十三、请说明static关键字是什么意思?java中是否可以覆盖一个private或者static的方法?

答:static关键字标明一个成员变量或者是成员方法可以在没有所属的类的是实例变量的情况下被访问。

java中static方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而static方法是编译时静态绑定的。

static方法跟类的任何实例都不相关,所以概念上不适用。

二十四、请列举你锁知道的Object类的方法并简要说明?

答:①clone()创建并返回此对象的一个副本,它是Object默认构造方法;

②equals(Object obj)指是某个其他对象是否与此对象“相等”。

③toString()返回该对象的字符串表示。

④finalize()当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。

⑤getClass()返回一个对象的运行时类。

⑥hashCode():返回该对象的哈希码。

二十五、请说明类和对象的区别?

答:①类是对某一类事物的描述,是抽象的;而对象是一个实实在在的个体,是类的一个实例;

②对象是函数、变量的集合体;而类是一组函数和变量的集合体,即类是一组具有相同属性的对象集合体。

二十六、请解释一下String为什么不可变?

答:不可变对象是指一个对象的状态在对象被创建之后就不再变化。不可改变的意思就是说:不能改变对象内的成员变量,包括基本数据类型的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变。

String不可变是因为在JDK中String类被声明为一个final类,且类内部的value字节数组也是final的,只有当字符串是不可变时字符串池才有可能实现,字符串池的实现可以在运行时节约很多heap空间,因为不同的字符串变量都指向池中的同一个字符串;如果字符串是可变的则会引起很严重的安全问题,譬如数据库的用户名密码都是以字符串的形式传入来获得数据库的连接,因为字符串是不可变的,所以它的值是不可变的。否则则黑客们可以钻孔子改变字符串指向的对象的值造成安全漏铜;因为字符串是不可变的,所以是线程安全的,同一字符串实例可以被多个线程共享,这样便不用因为线程安全问题而使用同步,字符串自己便是线程安全的。因为字符串是不可变的所以在它创建的时候hashcode就被缓存了,不可变性页保证了hash码的唯一性,不需要重新计算,这就使得字符串很适合作为map的键,字符串的处理速度要快过其他键对象,这就是Hashmap中的键往往都使用字符串的原因。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值