`

java初学细节(一)

    博客分类:
  • java
阅读更多

      对于这个系列里的问题,每个学Java的人都应该搞懂。当然,如果只是学Java玩玩就无所谓了。如果你认为自己已经超越初学者了,却不很懂这些问题,请将你自己重归初学者行列。内容均来自于CSDN的经典老贴。

  问题一:我声明了什么!

  String s = "Hello world!";

  许多人都做过这样的事情,但是,我们到底声明了什么?回答通常是:一个String,内容是“Hello world!”。这样模糊的回答通常是概念不清的根源。如果要准确的回答,一半的人大概会回答错误。

  这个语句声明的是一个指向对象的引用,名为“s”,可以指向类型为String的任何对象,目前指向 "Hello world!"这个String类型的对象。这就是真正发生的事情。我们并没有声明一个String对象,我们只是声明了一个只能指向String对象的引用变量。所以,如果在刚才那句语句后面,如果再运行一句:

  String string = s;

  我们是声明了另外一个只能指向String对象的引用,名为string,并没有第二个对象产生,string还是指向原来那个对象,也就是,和s指向同一个对象。

  问题二:"=="和equals方法究竟有什么区别?

  ==操作符专门用来比较变量的值是否相等。比较好理解的一点是:

  int a=10;

  int b=10;

  则a==b将是true。

  但不好理解的地方是:

  String a=new String("foo");

  String b=new String("foo");

  则a==b将返回false。

  根据前一帖说过,对象变量其实是一个引用,它们的值是指向对象所在的内存地址,而不是对象本身。a和b 都使用了new操作符,意味着将在内存中产生两个内容为"foo"的字符串,既然是“两个”,它们自然位于不同的内存地址。a和b的值其实是两个不同的内存地址的值,所以使用"=="操作符,结果会是false。诚然,a和b所指的对象,它们的内容都是"foo",应该是“相等”,但是==操作符并不涉及到对象内容的比较。

  对象内容的比较,正是equals方法做的事。

  看一下Object对象的equals方法是如何实现的:

  boolean equals(Object o){

  return this==o;

  }

  Object对象默认使用了==操作符。所以如果你自创的类没有覆盖equals方法,那你的类使用 equals和使用==会得到同样的结果。同样也可以看出,Object的equals方法没有达到equals方法应该达到的目标:比较两个对象内容是否相等。因为答案应该由类的创建者决定,所以Object把这个任务留给了类的创建者。

  看一下一个极端的类:

  Class Monster{

  private String content;

  ...

  boolean equals(Object another){ return true;}

  }

  我覆盖了equals方法。这个实现会导致无论Monster实例内容如何,它们之间的比较永远返回true。

  所以当你是用equals方法判断对象的内容是否相等,请不要想当然。因为可能你认为相等,而这个类的作者不这样认为,而类的equals方法的实现是由他掌握的。如果你需要使用equals方法,或者使用任何基于散列码的集合(HashSet, HashMap,HashTable),请察看一下java doc以确认这个类的equals逻辑是如何实现的。

  问题三:String到底变了没有?

  没有。因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。请看下列代码:

  String s = "Hello";

  s = s + " world!";

  s所指向的对象是否改变了呢?从本系列第一篇的结论很容易导出这个结论。我们来看看发生了什么事情。在这段代码中,s原先指向一个String对象,内容是"Hello",然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个String对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。

  通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个 String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。

  同时,我们还可以知道,如果要使用内容相同的字符串,不必每次都new一个String。例如我们要在构造器中对一个名叫s的String引用变量进行初始化,把它设置为初始值,应当这样做:

  public class Demo {

  private String s;

  ...

  public Demo {

  s = "Initial Value";

  }

  ...

  }

  而非

  s = new String("Initial Value");

  后者每次都会调用构造器,生成新对象,性能低下且内存开销大,并且没有意义,因为String对象不可改变,所以对于内容相同的字符串,只要一个String对象来表示就可以了。也就说,多次调用上面的构造器创建多个对象,他们的String类型属性s都指向同一个对象。

分享到:
评论

相关推荐

    java初学者细节资料

    java入门的一些细节资料,有兴趣的可以下下来看看

    java细节总结 非常适合初学者学习

    java细节总结 非常适合初学者学习java细节总结 非常适合初学者学习

    java实战练习+ 从”helloworld"到“大型病毒传染”难度“ + Java初学者 + Java习题

    1. 该资源适合刚刚接触java的同学们,通过此练习题,可以更加深刻的理解java语法的内涵,同时熟悉java的使用方法。 2. 在做acm题不能有很好效果的情况下,这个是很好的选择。 3. 题目考察点含有( 类,继承,多态,...

    基于UDP通信的联机对战,基于JAVAGUI,适合java初学者练习的一款小游戏.zip

    Java语言游戏项目实战资源包 内容概览: 这次分享为你带来了丰富的Java语言游戏项目实战资源,让你在实践中深入掌握Java语言,并开启游戏开发之旅。资源包中包括: 游戏项目代码:精心挑选了多个经典的小游戏项目...

    java初学者应该知道的一些知识

     解决问题的关键在于抽象化:在Java语言里,可以给出一个或多个抽象Java类或Java接口,规定出所有的具体类必须提供的方法特征作为系统设计的抽象层。这个抽象层预见了所有的可能扩展,因此,在任何扩展情况下都不会...

    Java语言规范中文版(第三版)

    本书由“java之父”Jame Gosling 以及另外三位顶级大师撰写而成,无论是对java语言的初学者还是专业程序员都具有极高的价值,是关于java程序设计语言最权威的技术参考书。 本书侧重于java技术细节和内幕,全面,准确...

    一个桌面程序,通过游戏闯关的方式来了解一些java的语言细节。.zip

    用java写的项目,适合初学者学习,在这里免费分享给大家,欢迎下载使用。用java写的项目,适合初学者学习,在这里免费分享给大家,欢迎下载使用。用java写的项目,适合初学者学习,在这里免费分享给大家,欢迎下载...

    Java多线程初学者指南

    Java多线程初学者指南,共12篇文档,由浅入深,举例说明,包括一些疑点都解释得很清楚,类,方法,属性同步的区别等细节也都介绍得很全面,是个很好的学习资料。

    疯狂Java:突破程序员基本功的16课[2]

     在本书中,李刚老师一改枯燥的教学方式,专门面向java初学者可能会遇到的各种学习问题,由点及面,详细讨论了java内存管理、java编程过程中常遇陷阱、常用数据结构的java实现和java程序开发的方法与经验等内容。...

    疯狂Java:突破程序员基本功的16课[3]

     在本书中,李刚老师一改枯燥的教学方式,专门面向java初学者可能会遇到的各种学习问题,由点及面,详细讨论了java内存管理、java编程过程中常遇陷阱、常用数据结构的java实现和java程序开发的方法与经验等内容。...

    疯狂Java:突破程序员基本功的16课[1]

     在本书中,李刚老师一改枯燥的教学方式,专门面向java初学者可能会遇到的各种学习问题,由点及面,详细讨论了java内存管理、java编程过程中常遇陷阱、常用数据结构的java实现和java程序开发的方法与经验等内容。...

    疯狂Java:突破程序员基本功的16课

    在《疯狂Java:突破程序员基本功的16课(修订版)》中,李刚老师专门针对Java初学者可能会遇到的各种学习问题,由点及面,详细讨论了Java内存管理、Java编程过程中常遇陷阱、常用数据结构的Java实现和Java程序开发...

    Java.xmind Java全面总结思维导图

    本资源含有百分之八十的Java技术总结,内容丰富,细节到位,适合Java初学者以及Java学习过半者,总结清晰明了,有很好的构建知识网络作用

    java 五子棋简单版源代码

    一个简单的五子棋程序,是我在上java课程时候的一个小练习,比较简单,主要是为了锻炼逻辑思维能力,一点点小的体会:做程序的时候 或许没有思路,但是可以先架设大的框架,有一个大概要做成的样子要在大脑中形成,...

    [Java算法-排序]归并排序.java

    此外,文档还包括一个逐步指南,介绍如何在Java中实现归并排序,包括详细的代码示例和实现细节。 文档还涵盖了高级主题,如如何优化代码以提高性能以及如何处理大的数组。该资源包括实用练习,让读者可以练习在Java...

    疯狂JAVA:突破程序员基本功的16课 源代码

    在《疯狂Java:突破程序员基本功的16课》中,李刚老师一改枯燥的教学方式,专门面向Java初学者可能会遇到的各种学习问题,由点及面,详细讨论了Java内存管理、Java编程过程中常遇陷阱、常用数据结构的Java实现和Java...

    [Java算法-排序]希尔排序.java

    此外,文档还包括一个逐步指南,介绍如何在Java中实现希尔排序代码,包括详细的代码示例和实现细节。 文档还涵盖了高级主题,如如何优化代码以提高性能以及如何处理大的数组。该资源包括实用练习,让读者可以练习在...

    [Java算法设计]-两串旋转.java

    此外,文档还包括一个逐步指南,介绍如何在Java中实现两个字符串旋转的代码,包括详细的代码示例和实现细节。 文档还涵盖了高级主题,如如何处理包含重复字符的字符串以及如何优化代码以提高性能。该资源包括实用...

Global site tag (gtag.js) - Google Analytics