Java面试高频(三)

1.switch 语句能否作用在 byte 上,能否作用在 long 上,能否作用在 String 上?

在switch(expr1)中,expr1只能是一个整数表达式或者枚举常量(更大字体),整数表达式可以是int基本类型或Integer包装类型,由于,byte,short,char都可以隐含转换为int,所以,这些类型以及这些类型的包装类型也是可以的。显然,long、double、boolean以及他们的包装类和String类型都不符合switch的语法规定,并且不能被隐式转换成int类型,所以,它们不能作用于swtich语句中。但是在JDK7的新特性中,switch语句可以用String。

2.final、finally、finalize 的区别

final:final是一个修饰符,可以修饰类,方法和变量。final修饰类表示类不能被其它类继承,并且该类中的所有方法都会隐式的被final修饰。final修饰方法,则该方法不能被重写,若父类中final方法的访问权限为private,将导致子类中不能直接继承该方法,因此,此时可以在子类中定义相同方法名的函数,此时不会与重写final的矛盾,而是在子类中重新地定义了新方法。当final修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变化;如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。本质上是一回事,因为引用的值是一个地址,final要求值,即地址的值不发生变化。

finally:finally作为异常处理的一部分,它只能用在try/catch语句中,并且附带一个语句块,表示这段语句最终一定会被执行(不管有没有抛出异常),经常被用在需要释放资源的情况下。但须注意,在某些特殊情况下,finally块是不会执行的。

finalize:finalize()是Object中定义的一个方法,也就是每个对象都有这个方法。当垃圾回收器确定不存在对该对象的更多引用时(是个垃圾),由对象的垃圾回收器调用此方法。子类重写 finalize 方法,以配置系统资源或执行其他清除,例如:一个socket链接,在对象初始化时创建,整个生命周期内有效,那么就需要实现finalize,关闭这个链接。

3.== 和 equals 的区别?

1.==是操作符,equals是方法。

2.==对于基本类型(如short、int、long、float、double)和引用类型是不一样的,基本类型:比较的是值是否相同,引用类型:比较的是引用是否相同,即比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象,比较的是真正意义上的指针操作。

3.equals 本质上就是 ==,equals用来比较的是两个对象的内容是否相等,由于所有的类都是继承自java.lang.Object类的,所以适用于所有对象,如果没有对该方法进行覆盖的话,调用的仍然是Object类中的方法,而Object中的equals方法返回的却是==的判断。只不过 String 和 Integer 等重写了 equals 方法,把它变成了值比较。

equals方法没有被重写的情况下:

  public boolean equals(Object obj) {
      return (this == obj);
  }

equals方法被重写的情况下:(String为例)

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

4.两个对象的 hashCode() 相同,则 equals() 也一定为 true 吗?

  • 两个对象equals相等,则它们的hashCode()必须相等,反之则不一定。
  • 两个对象==相等,则其hashCode()一定相等,反之不一定成立。

5.为什么重写 equals() 就一定要重写 hashCode() 方法?

1.当我们将equals方法重写后有必要将hashCode方法也重写,这样做才能保证不违背hashCode方法中“相同对象必须有相同哈希值”的约定。

2.由hashCode方法的源码注释得知:

  • hashCode方法本质就是一个哈希函数,将对象的地址值映射为integer类型的哈希值。

  • 一个对象多次调用它的hashCode方法,应当返回相同的integer(哈希值)。

  • 两个对象如果通过equals方法判定为相等,那么就应当返回相同integer。

  • 两个地址值不相等的对象调用hashCode方法不要求返回不相等的integer,但是要求拥有两个不相等integer的对象必须是不同对象。

3.所以equals方法与hashCode方法根本就是配套使用的。对于任何一个对象,不论是使用继承自Object的equals方法还是重写equals方法。hashCode方法实际上必须要完成的一件事情就是,为该equals方法认定为相同的对象返回相同的哈希值。Object类中的equals方法区分两个对象的做法是比较地址值,即使用“==”。而我们如若根据业务需求改写了equals方法的实现,那么也应当同时改写hashCode方法的实现。否则hashCode方法依然返回的是依据Object类中的依据地址值得到的integer哈希值。

6.& 和 && 的区别?

&&和&都可以表示逻辑与,但他们是有区别的,共同点是他们两边的条件都成立的时候最终结果才是true;

不同点是&&只要是第一个条件不成立为false,就不会再去判断第二个条件,最终结果直接为false,而&判断的是所有的条件;

7.Java 中的参数传递时传值呢?还是传引用?

值传递:是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

引用传递:是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

Java中的传递只有值传递而没有引用传递,只不过传递为基本数据类型的话,是复制的数值,而对象类型的话,则是复制的对象存放地址。

8.Java 中的 Math.round(-1.5) 等于多少?

Math.round() 方法返回一个最接近的 int、long 型值,四舍五入。

round 表示"四舍五入",算法为Math.floor(x+0.5) ,即将原来的数字加上 0.5 后再向下取整,所以 Math.round(11.5) 的结果为 12,Math.round(-11.5) 的结果为 -11。

public class Test {
    public static void main(String []args) {
       System.out.println( Math.round(-1.5));
    }
}

结果为:-1

参考文档

点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注