Java面向对象面试题

1. Java面向对象的知识结构

  • 1.1 Java语法以及关键字、如接口与类、内部类,final/finally/finalize, throw/throws,域访问符权限等;

  • 1.2 Java面向对象思想以及体系,例如设计思想。

2. 经典面试题

2.1 Java 有没有 goto? 如果有,一般用在什么地方?如果没有,如何跳出当前的多重嵌套循环?

goto是Java中的保留字,在目前Java版本中没有使用。

在Java中跳出多重循环的的方法有三种:

1. break + 标签,在外层循环前加上一个标签lable,
然后在最里层循环使用 break lable.

public static void main(String[] args) {
    label:    //标记
    for (int i = 0 ; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
                System.out.println("i = " + i + ", j = " + j);
            if(j == 5) {  //满中一定条件跳到某个标记
                break label;
            }
        }
    }
}

2. 通过异常捕获

public static void main(String[] args) {
	try {
    	for (int i = 0; i < 10; i++) {
        	for (int j = 0; j < 10; j++) {
            	System.out.println("i = " + i + ", j = " + j);
            	if (j == 5) {// 满足一定条件抛异常
                	throw new RuntimeException("test exception for j = 5");
            	}
        	}
    	}
	} catch (RuntimeException e) { //循环外层捕获异常
    	e.printStackTrace();
	}
}


3. 通过标置变量

 public static void main(String[] args) {
    boolean flag = false; //初始化标置变量
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
            System.out.println("i = " + i + ", j = " + j);
            if (j == 5) {   //满足一定条件进行设置标置变量
                flag = true;
            }
            if (flag) { //内层循环判断标置变量
                break;
            }

        }
        if (flag) {//外层循环判断标置变量
            break;
        }
    }
}

2.2 抽象类(abstract class)和接口(interface)有什么异同?

  • 相同点

      1. 不能直接实例化。如果要实例化,抽象变量必须实现所有抽象方法,接口变量必须实现接口未实现的方法。
      2. 都可以有实现方法(Java1.8之前不能有实现方法)
      3. 都可以不需要实现类或者继承者去实现所有方法(Java8 以前的接口,Java8 及以后的接口中可以包括默认方法,不需要实现者实现)。
    
  • 不同点

      1. 抽象类和接口所反映的设计理念不同,抽象类表示的是对象/类的抽象,接口表示的是行为的抽象。
      
      2. 抽象类不可以多重继承,接口可以多重继承。即一个类只能继续一个抽象类,却可以继承多个接口。
       
      3. 抽象类中的方法可以用 public protected 和 default abstract 修饰符,不能用 private、static、synchronize、native 修饰;变量可以在子类中重新定义,也可以重新赋值;
      接口的方法默认修饰符是 public abstract, Java8 开始出现静态方法,多加 static 关键字;变量默认是 public static final 型,且必须给其初值,在实现类中也不能重新定义,也不能改变其值。
    
      4. 抽象类可以有构造器,接口没有构造器。
    

2.3 Java 创建对象的方式有哪些?

1. 使用 new关键字
2. 反射创建,使用java.lang.Class 类的newInstance 方法

这种方式会调用无参的构造函数来创建对象,有两种实现方式。

//方式一,使用全路径包名
User user = (User)Class.forName("com.imooc.interview.demo.User").newInstance(); 
//方法二,使用class类
User user = User.class.newInstance();

反射,使用 java.lang.reflect.Constructor 类的 newInstance 方法。

Constructor<User> constructor = User.class.getConstructor();
User user = constructor.newInstance();

使用 clone 方法。

public class User implements  Cloneable {
/** 构造方法 */
public User(Integer age) {
    this.age = age;
}

public Integer getAge() {
    return age;
}

private Integer age;

// 重写(Overriding)Object的clone方法
@Override
protected User clone() throws CloneNotSupportedException {
    return (User) super.clone();
}


public static void main(String[] args) throws Exception {
    User person = new User(new Integer(200));
    User clone = person.clone();
    System.out.println("person == clone, result =  " +  (person == clone));  // false,拷贝都是生成新对象
    System.out.println("person.age == clone.age, result =  " +  (person.getAge() == clone.getAge())); // true,浅拷贝的成员变量引用仍然指向原对象的变量引用
}

}

浅拷贝和深拷贝

  • 浅拷贝:被复制对象的所有变量都含有与原来的对象相同的值,对拷贝后对象的引用仍然指向原来的对象。

  • 深拷贝:不仅要复制对象的所有非引用成员变量值,还要为引用类型的成员变量创建新的实例,并且初始化为形式参数实例值。

      3. 使用反序列化。
      为了序列化 / 反序列化一个对象,需要该类实现空接口 Serializable
      
      序列化时首先创建一个输出流对象 oos, 使用 oos 的 writeObject () 方法将 p 对象写入 oos 对象中去。使用反序列化创建对象时,首先创建一个输入流对象 ois,使用输入流对象 ois 的 readObject () 方法将序列化存入的对象读出,重新创建一个对象。
    
      序列化是深拷贝。
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李同学va

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值