java初学者必须理解这几个问题

关于这个系列里的问题,每个学Java的人都应该搞懂。当然,若是仅仅学Java玩玩就无所谓了。若是你以为本人现已逾越初学者了,却不很懂这些问题,请将你本人重归初学者队伍。

问题一:我声明晰什么!

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培训以为它们代表同一个String方针。而用关键词new调用结构器,总是会创立一个新的方针,无论内容能否一样。
至于为什么要把String类描绘成不行变类,是它的用处决议的。其实不只 String,许多Java规范类库中的类都是不行变的。在开发一个体系的时分,咱们有时分也需求描绘不行变类,来传递一组关联的值,这也是面向方针思维的表现。不行变类有一些长处,比方由于它的方针是只读的,所以多线程并发拜访也不会有任何问题。当然也有一些缺陷,比方每个不一样的状况都要一个方针来代表,能够会形成功能上的问题。所以Java规范类库还供给了一个可变版别,即StringBuffer。

(0)

相关推荐

  • Java初学者问题图解(动力节点Java学院整理)

    1. String对象不可改变的特性 下图显示了如下代码运行的过程: String s = "abcd"; s = s.concat("ef"); 图1 2. equals()与hashCode()方法协作约定 HashCode(哈希编码,散列码)是设计了用来提高性能的. equals()与hashCode()方法之间的关系可以概括为: 1.如果两个对象相等(equal),那么必须拥有相同的哈希码(hash code) 2.即使两个对象有相同的哈希值(hash co

  • Java初学者常问的问题(推荐)

    本文介绍一些Java初学者常问的问题,可以用%除以一个小数吗? a += b 和 a = a + b 的效果有区别吗? 声明一个数组为什么需要花费大量时间? 为什么Java库不用随机pivot方式的快速排序? 基本数据类型 Q. 为什么 -0/3 结果是 0,而 -0.0/3.0 结果是 -0.0?(注意后边的结果0带负号) A. 在Java里,整数是用补码表示的.在补码中0只有一种表示方法.另一方面,浮点数则是用 IEEE 标准表示的, 对于0有两种表示方法, 0 和 -0. Q. 我可以用

  • java初学者必须理解这几个问题

    关于这个系列里的问题,每个学Java的人都应该搞懂.当然,若是仅仅学Java玩玩就无所谓了.若是你以为本人现已逾越初学者了,却不很懂这些问题,请将你本人重归初学者队伍. 问题一:我声明晰什么! String s = "Hello world!"; 许多人都做过这样的事情,但是,我们到底声明了什么?回答通常是:一个String,内容是"Hello world!".这样模糊的回答通常是概念不清的根源.如果要准确的回答,一半的人大概会回答错误. 这个语句声明的是一个指向对

  • 适用于Java初学者的学习路线图

    对于Java初学者来说,想学习Java教程,需要明白,基础打好才能学得更好,Java教程之学习Java的路线图的五个必经阶段,希望能对Java学习者有所帮助. 第一个阶段-java基础阶段 1.java语法 2.面向对象 3.常用的api 4.界面编程 5.多线程 6.文件io 7.java网络编程.. 这是学习java开发的基础阶段,也是以后的学习基石. 第二个阶段-数据库阶段 1.oracle 2.mysql 3.sql server 目前中国软件公司用的最多的三大主流数据库是sql ser

  • 一个牛人给Java初学者的建议(必看篇)

    给初学者之一:浅谈Java及应用学java 从不知java为何物到现在一个小小的j2ee项目经理虽说不上此道高手,大概也算有点斤两了吧每次上网,泡bbs逛论坛,没少去java相关的版 面总体感觉初学者多,高手少,精通的更少由于我国高等教育制度教材陈旧,加上java自身发展不过十年左右的时间还有一个很重要的原因就是java这门语 言更适合商业应用所以高校里大部分博士老师们对此语言的了解甚至不比本科生多在这种环境下,很多人对java感到茫然,不知所措,不懂java能做什么即 便知道了java很有用,

  • Java初学者了解"=="与equals的区别

    这篇文章主要介绍了Java初学者了解"=="与equals的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.基本数据类型当中,"=="比较的是两个变量的值 int a=5; int b=4; int c=5; System.out.println(a==b);//false System.out.println(a==c);//true 2.引用数据类型当中,"=="比较的是两个对象在内

  • Java语言的11大特点(Java初学者必知)

    Java简介 Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承.指针等概念,因此Java语言具有功能强大和简单易用两个特征. Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程  . Java具有简单性.面向对象.分布式.健壮性.安全性.平台独立与可移植性.多线程.动态性等特点 Java可以编写桌面应用程序.Web应用程序.分布式系统和嵌入式系统应用程序等 . Java是一种简单的,面向对

  • java初学者如何让编程学习起来更简单

    如果不喜欢学Java就不要学了,硬要逼着自己去学到头来也会是一知半解.不仅浪费时间,也浪费金钱,如果喜欢Java那就继续学,并且努力学,学好Java会有意想不到的好处.学习Java会有一个很艰难的过渡期,在此期间你要努力学好它并度过它,那么你就成功了.学任何东西,入门的时候,觉得难或者吃力是很正常的事情,小学生学习个加减乘除不也花了三四年的时间吗? 行百里者半九十,从0到1是最艰难最吃力的一步,先慢后快,怕的是中途放弃.而你当年读小学的时候却不会- 1.很多人还没学习JAVA就开始觉得java很

  • Java中难理解的四个概念

    前言 Java 是很多人一直在用的编程语言,但是有些 Java 概念是非常难以理解的,哪怕是一些多年的老手,对某些 Java 概念也存在一些混淆和困惑. 所以,在这篇文章里,会介绍四个 Java 中最难理解的四个概念,去帮助开发者更清晰的理解这些概念: 匿名内部类的用法 多线程 如何实现同步 序列化 匿名内部类 匿名内部类又叫匿名类,它有点像局部类(Local Class)或者内部类(Inner Class),只是匿名内部类没有名字,我们可以同时声明并实例化一个匿名内部类. 一个匿名内部类仅适用

  • java迷宫算法的理解(递归分割,递归回溯,深搜,广搜)

    最近这学期做了一个java迷宫的课程设计,这里代码及其算法逻辑就分享出来. 首先简单的说一下其中我使用的算法(自动生成地图:递归分割法.递归回溯法:寻找路径:深度优先.广度优先算法) 递归分割法: 地图外面一圈被墙围住,然后在空白区域生成十字墙壁,再随机选择三面墙,将其打通,这样就能保证迷宫的流动性,再分别对刚才分好的四个区域以同样的方式执行分割,一直递归下去,直到空间不足以分割就return. 递归回溯法: 递归回溯法与深度优先算法在大致算法上其实差不多,具体只有一些细微的差别,都是通过判断当

随机推荐