包装类中的面试题
@Test
public void test1(){
//我们在三元运算符提到过:对于表达式1:表达式2;它们两个必须能够统一成同一种类型
//一个int和一个double会发生自动类型提升的都提升为double
Object o1 = true ?new Integer(1) : new Double(2.0);
System.out.println(o1);//输出结果为1.0
}
@Test
public void test2(){//这个不要求类型统一
Object o2;
if(true)
o2=new Integer(1);
else
o2=new Double(2.0);
System.out.println(o2);//1
}
public void test3(){
Integer i= new Integer(1);
Integer j= new Integer(1);
System.out.println(i==j);//false
//Integer内部定义了IntegerCache结构,Integer[]数组
//保存了从-128~127范围的整数。如果我们使用自动装箱的方式,给Integer赋值的范围在
//-128~127范围内时,可以直接使用数组中的元素,不用再去new了。目的:提高效率
Integer m=1;
Integer n=1;
System.out.println(m==n);//true
Integer x=128;//相当于new了一个Integer对象
Integer y=128;//相当于new了一个Integer对象
System.out.println(x==y);//false
}
说明:int的自动装箱,是系统执行了Ingeger.valueOf(int i),先看看Ingeger.java的底层源码
public static Integer valueOf( int i) {
if (i >= - 128 && i <= IntegerCache.high) // 没有设置的话,IngegerCache.high 默认是127
return IntegerCache.cache[i + 128 ];
else
return new Integer(i);
}
对于-128到127(默认是127)之间的值,Integer.valueOf(int i)返回的是缓存的Integer对象(并不是新建的对象)
所以范例中,m和n实际上是指向同一个对象。
而其他值,执行Integer.valueOf(int i)返回的是一个新建的Integer对象,所以范例中x和y指向的是不同的对象。
多态中的面试题
//考查多态的笔试题目:
public class InterviewTest1 {
public static void main(String[] args) {
Base1 base = new Sub1();//多态(向上转型)
//子类中的public void add(int a, int[] arr)会被认为是
//父类中的public void add(int a, int... arr)的重写方法
//因为我们在讲可变参数的时候就说过同类型的数组和可变参数不能同时出现
//我们在下面演示一下
base.add(1, 2, 3);//此行会调用子类中的public void add(int a, int[] arr)方法
//sub_1
Sub1 s = (Sub1)base;//向下转型
//我们说过当同时出现可变参数:public void add(int a, int[] arr)和精确的这种形参的时候:public void add(int a, int b, int c)
//都可执行的时候,会执行public void add(int a, int b, int c)
s.add(1,2,3);
}
}
class Base1 {
public void add(int a, int... arr) {
System.out.println("base1");
String str="ab";
}
}
class Sub1 extends Base1 {
public void add(int a, int[] arr) {
System.out.println("sub_1");
}
public void add(int a, int b, int c) {
System.out.println("sub_2");
}
public void eat(String[] foods){
}
//报错:Duplicate method eat(String...) in type Sub1
// public void eat(String... foods){
//
//
}
}
2.如何证明多态是运行时行为还是编译时行为
import java.util.Random;
//面试题:多态是编译时行为还是运行时行为?
//证明如下
class Animal{
protected void eat(){
System.out.println("animal eat food");
}
}
class Cat extends Animal{
protected void eat(){
System.out.println("cat eat fish");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("Dog eat bone");
}
}
class Sheep extends Animal{
public void eat(){
System.out.println("sheep eat grass");
}
}
public class InterviewTest {
public static Animal getInstance(int key){
switch(key){
case 0:
return new Cat();
case 1:
return new Dog();
default:
return new Sheep();
}
}
public static void main(String[] args){
int key=new Random().nextInt(3);
System.out.println(key);
Animal animal=getInstance(key);
animal.eat();
}
}
我们先先定义一个随机数。 接下来调用一下getInstance方法,getInstance方法会根据随机数的不同,new不同的对象,然后返回赋给Animal(此时发送了多态)。这时候在调用eat方法。
因为我们根据代码无法看出结果,只有真正运行时才知道new的是谁!
相关结论: 虚拟方法调用(多态情况下) 子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法。 父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。
final关键字中的面试题
1、
public class Something {
public int addOne(final int x) {
// return ++x;
//++x相当于x=x+1;你又进行了重写赋值
return x + 1;//允许的
}
}
2、
public class Something1 {
public static void main(String[] args) {
Other o = new Other();
new Something1().addOne(o);
}
public void addOne(final Other o) {
// o = new Other();错误
o.i++;
//o不能再引用其他对象,但对于o对象里面的变量(不是final修饰的)是可以改变的
}
}
class Other {
public int i;
}
接口中的面试题
1、
interface A{
int x=1;
}
class B{
int x=1;
}
public class C extends B implements A{
public void pX(){
//编译不通过。The field x is ambiguous
//因为x是不明确的
// System.out.println(x);
//调用父类的
System.out.println(super.x);
//调用接口A的默认属性是public static 的
System.out.println(A.x);
}
public static void main(String[] args) {
new C().pX();
/*
* 输出:
* 1
1
*/
}
}
2、
错误之处:Ball类中的play方法中的:
ball=new Ball(“Football”);编译错误,因为我们本类没有ball这个引用,只能去接口中找,发现是在接口Rollable中定义的:Ball ball = new Ball(“PingPang”);我们指定接口中的引用是public static final修饰的,final修饰的引用是不能再指向其他对象的。
从本题也可以看到:Ball实现接口Playable和Bounceable中的play方法是对两者的实现,可以说是对Playable接口中的play方法实现也是对Bounceable接口中的play方法实现。
String中的面试题
1、
2、
public class StringTest {
String str=new String("good");
char[] ch={'t','e','s','t'};
public void change(String str,char ch[]){
str="test ok";
ch[0]='b';
}
public static void main(String[] args) {
StringTest st=new StringTest();
st.change(st.str,st.ch);
System.out.println(st.str);//good
System.out.println(st.ch);//best
String str="";//使用这种方式str这个对对象是有内存空间的,只是char[]value数组的长度为0,什么都没有
String str1=null;//这可是没有指向任何对象。
System.out.println(str.length());//0
}
}
3、
public class Person {
String name;
int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Person p1 = new Person("Tom",12);
Person p2 = new Person("Tom",12);
System.out.println(p1.name.equals(p2.name));//true
System.out.println(p1.name == p2.name);//true
p1.name = "Jerry";
System.out.println(p2.name);//Tom
}
}