java基础面试题系列(31 - 40)

20200709 by 1z

  1. 请说明java中的方法重写(Overriding)和方法重载(overloading)是什么意思?
方法的重写
* 方法的重写是针对于父子关系而言的,表示的是子对象去重写(覆盖)父对象的方法,重写的规律如下
(两同两小一大原则)
·	* 1. 保证方法的参数表列一致,方法名一致
 	* 2. 保证子类的返回类型 <= 父类方法的返回类型 
 	* 3. 保证子类的抛出异常类型 <= 父类方法的抛出异常类型
	* 4. 保证子类方法的权限修饰符 >= 父类方法的权限修饰符

方法的重载
* 方法重载就是在一个类种定义多个同名的方法,要求每个方法具有不同的参数类型或者参数个数不同(只限制参数表列不同),保证方法名相同即可。(方法的返回参数,修饰符,可以不同,也可以相同)
* main方法可以被重载
  1. 请说明Query接口的list方法 和 iterate方法有什么区别?
对于Query接口的list()方法与iterate()方法来说,都可以实现获取查询的对象

但是list()方法返回的每个对象都是完整的(对象中的每个属性都被表中的字段填充上了)

而iterator()方法所返回的对象中仅包含了主键值(标识符),只有当你对iterator中的对象进行操作时,Hibernate才会向数据库再次发送SQL语句来获取该对象的属性值。

参考链接: https://blog.csdn.net/jialinqiang/article/details/8718437
  1. 请你谈一下面向对象的·六原则一法则·
设计模式层面,是所有设计模式执行的基石
1. 单一职责原则: 一个类只做它该做的事情。(实现高内聚的特点)

2. 开闭原则: 软件实体对扩展开放,对修改关闭(在理想的情况下,扩展一个类无需修改原类的代码,而是直接加上新代码即可)

3. 接口隔离原则: 一个类对另外一个类的依赖,应该建立在接口上

4. 依赖倒转原则: 
高层模块和底层模块应该依赖于抽象;
抽象不应该依赖细节,细节依赖抽象;
依赖倒转的中心思想是面向接口编程

5. 里氏替换原则: 简单来说,所有使用基类的地方都可以透明的使用子类
	5-1: 在子类中尽量不要重写父类的方法
	5-2: 适当的情况下 可以使用聚合,组合,依赖来解决问题(父类和子类继承自同一个基类,父类子类取消继承关系 使用依赖聚合组合的方式替代继承)

6. 合成复用原则: 在代码中尽量使用聚合/组合的方法代替继承

7. 迪米特法则: 一个类对自己依赖的类知道的越少越好,尽量将逻辑封装到类的内部,对外提供方法调用(降低耦合度)

参考链接: https://blog.csdn.net/gaozongjian/article/details/79485264

  1. 请说明如何通过反射或者和设置私有字段的值?
1. 获取私有属性
public static void main(String[] args) throws NoSuchFieldException {
      // TODO Auto-generated method stub
/*
 * 使用反射来创建构造方法私有化的对象
 * */
      //1:获取类的无参构造方法
      Test test = new Test("张三");

      Method[] methods = Test.class.getMethods();
      //2. 获取私有属性
      Field[] fields = Test.class.getDeclaredFields();
      for (int i = 0; i < fields.length; i++) {
      	//表示这个属性 可以被访问
          fields[i].setAccessible(true);
          try {
              System.out.println(fields[i].get(test));
          } catch (IllegalArgumentException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          } catch (IllegalAccessException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
          //获取这个属性的名字
          System.out.println(fields[i].getName());
      }
  }
  
2. 获取私有方法
//获取所有的方法(不管是私有的 还是公有的)
Method[] methods2 = Test.class.getDeclaredMethods();
    for (int i = 0; i < methods2.length; i++) {
        //设置方法可以被访问
         methods2[i].setAccessible(true);
        //获取私有的方法名
         System.out.println(methods2[i].getName());
    }

3. 调用私有方法
Test test = new Test("张三");

Method[] methods = Test.class.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
    methods[i].setAccessible(true);
    try {
        //使用反射的功能进行方法的调用
        methods[i].invoke(test,"成功调用");
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println(methods[i].getName());
}


  1. 请说明重载 和 重写 的区别。重载的方法能否根据返回类型进行区分?

    参考 31问的解答
    
    方法的重写
    * 方法的重写是针对于父子关系而言的,表示的是子对象去重写(覆盖)父对象的方法,重写的规律如下
    (两同两小一大原则)
    ·	* 1. 保证方法的参数表列一致,方法名一致
     	* 2. 保证子类的返回类型 <= 父类方法的返回类型 
     	* 3. 保证子类的抛出异常类型 <= 父类方法的抛出异常类型
    	* 4. 保证子类方法的权限修饰符 >= 父类方法的权限修饰符
    
    方法的重载
    * 方法重载就是在一个类种定义多个同名的方法,要求每个方法具有不同的参数类型或者参数个数不同(只限制参数表列不同),保证方法名相同即可。(方法的返回参数,修饰符,可以不同,也可以相同)
    * main方法可以被重载
    
    在重载的时候,只需要保证每个方法有不同的参数表列(参数类型 or 参数的数量)即可,不能通过返回类型区分
    
    
  2. 请判断 两个对象值相同 x.equals(y) == true 但是可能有着不同的hashcode,这个说法是否正确,为什么?

从原则上来说是错的,因为根据 equals(Object) 方法,两个对象是相等的,则对象调用hashcode必定相等。

但是从实际操作上来看,可能存在,因为存在刻意重写了equals方法,但是没有重写hashcode()
[千万不要这样操作..]

public class EqualsTest {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        //true
        System.out.println(a.equals(b));
        
        //a.hashCode() != b.hashCode();
        System.out.println(a.hashCode() + "," + b.hashCode());
        
    }
}

class A {
    @Override
    public boolean equals(Object obj) {
        return true;
    }
}

class B {
}


  1. 请说明内部类可以引用他包含类的成员吗,如果可以,有什么样的限制?

    先对几种内部类做个简单的梳理:
    
    普通内部类
    1. 在一个类里面作为类的一个字段直接定义即可
    2. 此时普通的内部类对象是依赖于外部类对象而存在
    3. !内部类对象可以访问外部类中所有访问权限的字段,外部类可以通过内部类的对象引用从而访问内部类中定义的所有访问权限的字段
    4. 普通内部类中不能定义静态量
    
    
    静态内部类
    1. 静态内部类作为一个外部类的静态成员而存在,创建类的静态变量时不需要依赖外部对象
    2. 访问一个类的静态变量也无需依赖这个类的对象,因为它独立于所有类的对象
    3. !静态内部类中无法访问外部类的非静态成员(外部类的非静态成员属于每一个外部类对象,而静态内部类就是独立于外部类对象而存在的)
    4. 外部类可以访问静态内部类对象的所有权限成员
    
    
    局部内部类
    1. 其声明在一个方法体 / 一段代码块的内部,而且不在定义类的定义域之内便无法使用,
    2. 其提供的功能使用匿名内部类都可以实现,而本身匿名内部类可以写得比它更简洁,因此局部内部类用的比较少
    3. !在局部内部类里面可以访问外部类对象的所有访问权限的字段
    4. 而外部类却不能访问局部内部类中定义的字段,因为局部内部类的定义只在其特定的方法体 / 代码块中有效,一旦出了这个定义域,那么其定义就失效了,
    
    
    匿名内部类
    1. 常见写法 : 在方法参数中新建接口对象 or 类对象 并且实现
    2. !匿名内部类中可以使用外部类的所有属性,但是外部类不能使用匿名内部类中定义的属性
    3. 在匿名内部类中,外部类无法获取这个类的类名,无法获取它的属性信息
    
    因此,除了静态内部类不能使用外部类的非静态成员,其他都完全可以访问外部类所有的属性
    
  2. 请说明java语言如何进行异常处理,关键字throws,throw,try,catch,finally分别有什么意义? 在try中可以抛出异常嘛

在java中,根据面向对象的原则,将每一个异常封装成了一个对象,它是Throwable类或者子类的实例。
当一个方法出现异常之后可以抛出这个异常对象,同时异常对象会携带部分的异常信息,调用这个对象的方法可以获取异常信息。
或者在方法中采用try,catch的方式进行异常的处理。


throws:用来标明一个成员函数可能抛出的各种”异常” 
throw:明确抛出是哪种异常
try:如果哪一块程序中可能存在异常,可以使用try块包裹这一块异常。
catch: 可以在try后放置一个catch子句 catch内部携带了指定被捕捉异常的类型(在内部可以进行异常的处理)
finally: 无论异常是否被捕捉,总会执行该段代码,经常在内部放置一些关闭操作


在try中可以抛出异常
https://www.cnblogs.com/lulipro/p/7504267.html

  1. 请说明java的接口和c++的虚类的相同和不同处?
不同点
1. 一个子类只能继承一个抽象类(虚类),但能实现多个接口
2. 一个虚类可以有构造方法,接口没有构造方法
3. 一个虚类中的方法不一定是抽象方法,即其中的方法可以有实现(有方法体),接口中的方法都是抽象方法,不能有方法体,只有方法声明(java 1.8之前)(java1.8之后存在可以默认实现的方法)
4. 一个虚类可以是public、private、protected、default,接口只有public;
5. 一个虚类中的方法可以是public、private、protected、default,
   接口中的方法只能是public和default.
   
相同点:均都不能进行实例化

  1. 请判断当一个对象被当作参数传递给一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
java中只有值传递,不存在引用传递
当传递的是一个基础类型的时候,函数接收了原始值的一个副本,如果函数修改了该参数,则仅仅改变了副本,原始值不变。

当传递的是一个引用对象时,函数接收到的是对象的引用(地址),引用地址和实际参数指向了堆上的同一个地址,因此修改了引用变量,
实际参数也会受到影响。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值