面向对象
-
面向对象的四大特征
继承,封装,多态,抽象(只关注对象的有哪些行为和属性,不关心这些的细节是什么)。
-
为什么要用Clone? new一个对象和new一个clone的区别是什么?
当要重新使用A对象的属性,且在对其赋值的时候又不希望A对象有任何的改动时需要使用到克隆。
new一个对象是在堆内存中使用构造器重新生成一个对象。
new一个克隆是在堆内存中生成对象,然后把A对象的值重新原封不动的复制一份以达到和A对象分离的效果。
Person p = new Person(); Person p1= (Person) p.Clone();
深拷贝和浅拷贝的区别。 克隆属于浅拷贝。
想要使用clone就必须实现cloneable接口 , 该接口是一个标识接口。
克隆的浅拷贝与深拷贝的概念:
浅拷贝指的是在接口的实现类中重写clone方法,方法中调用super.clone()进行赋值。仅仅只会克隆对象的基本类型的值。遇到引用数据类型就会克隆其地址值,地址值如果被赋值那么原对象一样会改变。
深拷贝指的就是当克隆对象的时候就是完全赋值一份,引用数据类型在重写方法中进行逻辑重写,以达到克隆引用数据类型的效果,此时当引用类被赋值的时候就不会改变原对象的值。
深拷贝案例:
@Test public void cl() throws CloneNotSupportedException { Person person = new Person(28, '男'); //新建person User user = new User(1, "wz", 18,23,person); //新建user,形成本体 User u = (User)user.clone(); //对user进行克隆 u.getPerson().setAge(288); //对原地址进行修改 u.setId(1111); //设置克隆体的id u.setName("新名字"); //修改克隆体名字 //查看两个输出的区别 System.out.println("克隆体:"+u); //输出克隆 System.out.println("本体:"+user);//输出本体 }
package com.itheima.bean; public class Person implements Cloneable{ private int age ; private char sex; //克隆本体 @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } //删除其余方法,仅保留克隆方法,便于查看和对比
package com.itheima.bean; /* 用户的实体类 */ public class User implements Cloneable{ private Integer id; // 主键id private String name; // 姓名 private Integer age; // 年龄 private Integer search_count; //搜索数量 private Person person; //深拷贝 //本体克隆方法,会重新调用person的克隆方法对person属性进行赋值 @Override public Object clone() throws CloneNotSupportedException { User user =(User) super.clone(); Person person = (Person) user.person.clone(); user.setPerson(person); return user; } //删除其余方法,仅保留克隆方法,便于查看和对比 }
结果如下:
克隆体:User{id=1111, name='新名字', age=18, search_count=23, person=Person{age=288, sex=男}} 本体:User{id=1, name='wz', age=18, search_count=23, person=Person{age=28, sex=男}}
由此可以看出,已经实现了深拷贝。对克隆体的person进行赋值,不会影响本体。
浅拷贝案例:
直接super.clone()就可以实现。
public class User implements Cloneable{
private Integer id; // 主键id
private String name; // 姓名
private Integer age; // 年龄
private Integer search_count; //搜索数量
private Person person;
//深拷贝
//本体克隆方法,会重新调用person的克隆方法对person属性进行赋值
@Override
public Object clone() throws CloneNotSupportedException {
User user =(User) super.clone();
return user;
}
//删除其余方法,仅保留克隆方法,便于查看和对比
}
克隆体:User{id=1111, name='新名字', age=18, search_count=23, person=Person{age=288, sex=男}}
本体:User{id=1, name='wz', age=18, search_count=23, person=Person{age=288, sex=男}}
再次测试test,可以看出 person中的age已经发生变化,id和name未变化。
-
是否可以继承String ?
不能继承String类 因为是final修饰。底层是使用char数组实现的。
-
在方法中使用参数,且有对象被传入的时候,此时是值传递还是引用传递?
是值传递,java中仅有值传递。 当传递的是值的时候,传递的并非本体,而是一个副本值,传递引用类型的时候传递的是地址值。
-
char类型为什么能存储一个汉字?
char中类型默认 是以utf-16进行存储,此表中 一个汉字占用2个字节,所以可以存储。
-
五个常见运行时异常
NullPointException 空指针
ClassNotFoundException 找不到类
IndexOutOfBoundsException 数组越界
ClassCastException 数据类型转换异常
NumberFomatException 字符串转为数字异常
-
下列的结果是什么?
Integer f1=100,f2=100,f3=200,f4=400; System.out.println(f1==f2); System.out.println(f3==f4);
答案是 true,false
解析: 当给int的包装类赋值的时候,会在底层自行调用valueOf方法。
翻看源码可以发现在-128 - 127之间的值会在常量池中引用Integer对象,否则会new一个Integer对象出来。
因此 从常量池中取出来的相同的两个值,地址值必定相同为true。new出来的值进堆内存,故不相同为false
-
String、StringBufer、StringBuilder的区别
-
可变与不可变
String在编译时也是通过StringBuilder进行拼接,但是每次拼接都会重新生成一个String对象。每次拼接的字符串都是只用一次就重新指向,消耗大量资源。
StringBufer、StringBuilder都是可以通过自身不改变也不new新对象进行拼接的,效率更高。
-
线程安全
String 当对象被定义好了之后,线程安全。所有不可变类都是线程安全的。
StringBufer 线程安全 有同步锁 适用多线程
StringBuilder 线程不安全 用于单线程下对字符缓冲区进行操作
-
共同点
StringBufer、StringBuilde都继承于AbstractStringBuilder 抽象类
-
-
2
75页
-
2
-
2
-
2
-
2
-
2
-
2
-
2
-
2
-
2
-
2
-
2
-
2
-
2
-
2
-
2