夜光:Java成神之路(二)擅长的语言

夜光序言:

 

命中注定的人,并不是注定与之相爱、结合、交配的人。
命中注定的人,是为了令你成为你注定成为的样子而出现的人。

 

 
 
正文:
 
                                              以道御术 / 以术识道

 



 

3.3.2 深拷贝和浅拷贝

 
上面的示例代码中,Person 中有两个成员变量,分别是 name 和 age, name 是 String 类型, age 是 int 类型。代码非常简单,如下所示:
 
public class Person implements Cloneable{
   privat int age ;
   private String name;
 public Person(int age, String name) {
  this.age = age;
  this.name = name;
  }
 public Person() {}
 public int getAge() {
  return age;
  }
  public String getName() {
return name;
  }
  @Override
  protected Object clone() throws CloneNotSupportedException {
  return (Person)super.clone();
 }
} 

 

 
 
 
由于 age 是基本数据类型, 那么对它的拷贝没有什么疑议,直接将一个 4 字节的整数值拷贝过来就行。
 
但是 name 是 String 类型的, 它只是一个引用, 指向一个真正的 String 对象,那么对它的拷贝有两种方式:
直接将原对象中的 name 的引用值拷贝给新对象的 name 字段,
或者是根据原 Person 对象中的 name 指向的字符串对象创建一个新的相同的字符串对象,将这个新字符串对象的引用赋给新拷贝的 Person 对象的 name 字段。

 

 

这两种拷贝方式分别叫做浅拷贝和深拷贝。深拷贝和浅拷贝的原理如下图所示:

下面通过代码进行验证。

 
如果两个 Person 对象的 name 的地址值相同, 说明两个对象的 name 都指向同一个 String 对象,也就是浅拷贝, 而如果两个对象的 name 的地址值不同, 那么就说明指向不同的 String 对象, 也就 是在拷贝 Person 对象的时候, 同时拷贝了 name 引用的 String 对象, 也就是深拷贝。
 

验证代码如下:

 
 Person p = new Person(23, "zhang");
 Person p1 = (Person) p.clone();
 String result = p.getName() == p1.getName() ? "clone 是浅拷贝的" : "clone 是深拷贝的";
 System.out.println(result); 

 

 
 

打印结果为:


clone 是浅拷贝的 

 

 
所以,clone 方法执行的是浅拷贝, 在编写程序时要注意这个细节。

 

如何进行深拷贝:

由上一节的内容可以得出如下结论:如果想要深拷贝一个对象,这个对象必须要实现 Cloneable 接口,实现 clone方法,并且在 clone 方法内部, 把该对象引用的其他对象也要 clone 一份,这就要求这个被引用的对象必须也要实现 Cloneable 接口并且实现 clone 方法。
 
 
那么,按照上面的结论,实现以下代码 Body 类组合了 Head 类,要想深拷贝 Body 类,必须在 Body 类的 clone 方法中将 Head 类也要拷贝一份。
 

 

代码如下:

1.static class Body implements Cloneable{
2. public Head head;
3. public Body() {}
4. public Body(Head head) {this.head = head;}
5. @Override
6. protected Object clone() throws CloneNotSupportedException {
7. Body newBody = (Body) super.clone();
8. newBody.head = (Head) head.clone();
9. return newBody;
10. }
11.}
12.static class Head implements Cloneable{
13. public Face face;
14. public Head() {}
15. @Override
16. protected Object clone() throws CloneNotSupportedException {
17. return super.clone();
18. } }
19.public static void main(String[] args) throws CloneNotSupportedException {
20. Body body = new Body(new Head(new Face()));
21. Body body1 = (Body) body.clone();
22. System.out.println("body == body1 : " + (body == body1) );
23. System.out.println("body.head == body1.head : " + (body.head == body1.head));
24.} 

 

打印结果为:


1. body == body1 : false
2. body.head == body1.head : false

 

 

二、JavaSE 语法

 

1. Java 有没有 goto 语句?

goto 是 Java 中的保留字,在目前版本的 Java 中没有使用。
 
根据 James Gosling(Java 之父)编写的《The Java Programming Language》一书的附录中给出了一个 Java 关键字列表
 
 
其中有 goto 和 const,但是这两个是目前 无法使用的关键字,因此有些地方将其称之为保留字,其实保留字这个词应该有更广泛的意义,因为熟悉 C 语言的程 序员都知道,在系统类库中使用过的有特殊意义的单词或单词的组合都被视为保留字

 


 

2. & 和 && 的区别

 

&运算符有两种用法:(1)按位与;(2)逻辑与。
 
&&运算符是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是true 整个表达式的值才是 true。
 
&&之所以称为短路运算是因为,如果&&左边的表达式的值是 false,右边的表达式会被直接短路掉,不会进行运算。
 
 
 
很多时候我们可能都需要用&&而不是&,例如在验证用户登录时判定用户名不是 null 而且不是空字符串,应 当写为 username != null &&!username.equals(""),二者的顺序不能交换,更不能用&运算符
 
 
因为第一个条件如 果不成立,根本不能进行字符串的 equals 比较,否则会产生 NullPointerException 异常。

 

注意:逻辑或运算符(|) 和短路或运算符(||)的差别也是如此。


 

 

3. 在 Java 中,如何跳出当前的多重嵌套循环

 

在最外层循环前加一个标记如 A,然后用 break A;可以跳出多重循环。

 
(Java 中支持带标签的 break 和 continue语句,作用有点类似于 C 和 C++中的 goto 语句
 
但是就像要避免使用 goto 一样,应该避免使用带标签的 break 和 continue
 
因为它不会让你的程序变得更优雅,很多时候甚至有相反的作用)
 
 

 

4. 两个对象值相同 (x.equals(y) == true) ,但却可有不同的 hashCode,这句话对不对?

不对,如果两个对象 x 和 y 满足 x.equals(y) == true,它们的哈希码(hashCode)应当相同。
 
Java 对于 eqauls 方法和 hashCode 方法是这样规定的:
 
(1)如果两个对象相同(equals 方法返回 true),那么它们的 hashCode 值一定要相同;
 
(2)如果两个对象的 hashCode 相同,它们并不一定相同。
 
 
当然,你未必要按照 要求去做,但是如果你违背了上述原则就会发现在使用容器时,相同的对象可以出现在 Set 集合中,同时增加新元素 的效率会大大下降(对于使用哈希存储的系统,如果哈希码频繁的冲突将会造成存取性能急剧下降)。
 
 
关于 equals 和 hashCode 方法,很多 Java 程序员都知道,但很多人也就是仅仅知道而已,在 Joshua Bloch 的大作《Effective Java》(很多软件公司,《Effective Java》、《Java 编程思想》以及《重构:改善既有代码质量》

夜光:

是 Java 程序员必看书籍,如果你还没看过,那就赶紧去看电子书或者买............,中是这样介绍 equals 方法的。

 
首先 equals 方法必须满足自反性(x.equals(x)必须返回 true)、对称性(x.equals(y)返回 true 时,y.equals(x)也必须返回 true)、传递性(x.equals(y)和 y.equals(z)都返回 true 时,x.equals(z)也必须返回 true)和一致性(当 x 和 y 引用的对象信息没有被修改时,多次调用 x.equals(y)应该得到同样的返回值),而且对于任何非 null 值的引 用 x,x.equals(null)必须返回 false。
 
 

实现高质量的 equals 方法的诀窍包括:

 

1. 使用==操作符检查"参数是否为这个 对象的引用";
 
2. 使用 instanceof 操作符检查"参数是否为正确的类型";
 
3. 对于类中的关键属性,检查参数传入对象 的属性是否与之相匹配;
 
4. 编写完 equals 方法后,问自己它是否满足对称性、传递性、一致性;
 
5. 重写 equals 时 总是要重写 hashCode;
 
6. 不要将 equals 方法参数中的 Object 对象替换为其他的类型,在重写时不要忘掉 @Override 注解。

 


 

5. 是否可以继承 String

 

String 类是 final 类,不可以被继承

继承 String 本身就是一个错误的行为,对 String 类型最好的重用方式是关联关系(Has-A)和依赖关系(Use-A)而不是继承关系(Is-A)

 


 

 

6. 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

 

是值传递。

 
Java 语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。
 
对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的。
 
C++ 和 C#中可以通过传引用或传输出参数来改变传入的参数的值。
 
说明:Java 中没有传引用实在是非常的不方便,这一 点在 Java 8 中仍然没有得到改进,正是如此在 Java 编写的代码中才会出现大量的 Wrapper 类(将需要通过方法 调用修改的引用置于一个 Wrapper 类中,再将 Wrapper 对象传入方法)
 

 

这样的做法只会让代码变得臃肿,尤其是让从 C 和 C++转型为 Java 程序员的开发者无法容忍。

 

 


 

7. 重载(overload)和重写(override)的区别?重载的方法能否根据返回类型进行区分?

 

方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。
 
 
重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为 重载;
 
重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方 法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。
 
重载对返回类型没有特殊的要求。
 

方法重载的规则:

 
1.方法名一致,参数列表中参数的顺序,类型,个数不同。
 
2.重载与方法的返回值无关,存在于父类和子类,同类中。
 
3.可以抛出不同的异常,可以有不同修饰符。
 
 
 
 
 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
4S店客户管理小程序-毕业设计,基于微信小程序+SSM+MySql开发,源码+数据库+论文答辩+毕业论文+视频演示 社会的发展和科学技术的进步,互联网技术越来越受欢迎。手机也逐渐受到广大人民群众的喜爱,也逐渐进入了每个用户的使用。手机具有便利性,速度快,效率高,成本低等优点。 因此,构建符合自己要求的操作系统是非常有意义的。 本文从管理员、用户的功能要求出发,4S店客户管理系统中的功能模块主要是实现管理员服务端;首页、个人中心、用户管理、门店管理、车展管理、汽车品牌管理、新闻头条管理、预约试驾管理、我的收藏管理、系统管理,用户客户端:首页、车展、新闻头条、我的。门店客户端:首页、车展、新闻头条、我的经过认真细致的研究,精心准备和规划,最后测试成功,系统可以正常使用。分析功能调整与4S店客户管理系统实现的实际需求相结合,讨论了微信开发者技术与后台结合java语言和MySQL数据库开发4S店客户管理系统的使用。 关键字:4S店客户管理系统小程序 微信开发者 Java技术 MySQL数据库 软件的功能: 1、开发实现4S店客户管理系统的整个系统程序; 2、管理员服务端;首页、个人中心、用户管理、门店管理、车展管理、汽车品牌管理、新闻头条管理、预约试驾管理、我的收藏管理、系统管理等。 3、用户客户端:首页、车展、新闻头条、我的 4、门店客户端:首页、车展、新闻头条、我的等相应操作; 5、基础数据管理:实现系统基本信息的添加、修改及删除等操作,并且根据需求进行交流信息的查看及回复相应操作。
现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本微信小程序医院挂号预约系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此微信小程序医院挂号预约系统利用当下成熟完善的SSM框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的MySQL数据库进行程序开发。微信小程序医院挂号预约系统有管理员,用户两个角色。管理员功能有个人中心,用户管理,医生信息管理,医院信息管理,科室信息管理,预约信息管理,预约取消管理,留言板,系统管理。微信小程序用户可以注册登录,查看医院信息,查看医生信息,查看公告资讯,在科室信息里面进行预约,也可以取消预约。微信小程序医院挂号预约系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值