`

java初学细节(二)

    博客分类:
  • java
阅读更多

      上面的结论还基于这样一个事实:对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。

      至于为什么要把String类设计成不可变类,是它的用途决定的。其实不只String,很多Java标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本,即StringBuffer。

 

      问题四:final关键字到底修饰了什么?

 

      final使得被修饰的变量"不变",但是由于对象型变量的本质是“引用”,使得“不变”也有了两种含义:引用本身的不变,和引用指向的对象不变。

 

      引用本身的不变:

      final StringBuffer a=new StringBuffer("immutable");

      final StringBuffer b=new StringBuffer("not immutable");

      a=b;//编译期错误

 

      引用指向的对象不变:

      final StringBuffer a=new StringBuffer("immutable");

      a.append(" broken!"); //编译通过

 

      可见,final只对引用的“值”(也即它所指向的那个对象的内存地址)有效,它迫使引用只能指向初始指向的那个对象,改变它的指向会导致编译期错误。至于它所指向的对象的变化,final是不负责的。这很类似==操作符:==操作符只负责引用的“值”相等,至于这个地址所指向的对象内容是否相等,==操作符是不管的。

 

      理解final问题有很重要的含义。许多程序漏洞都基于此----final只能保证引用永远指向固定对象,不能保证那个对象的状态不变。在多线程的操作中,一个对象会被多个线程共享或修改,一个线程对对象无意识的修改可能会导致另一个使用此对象的线程崩溃。一个错误的解决方法就是在此对象新建的时候把它声明为final,意图使得它“永远不变”。其实那是徒劳的。

 

      问题五:到底要怎么样初始化!

 

      本问题讨论变量的初始化,所以先来看一下Java中有哪些种类的变量。

      1. 类的属性,或者叫值域

      2. 方法里的局部变量

      3. 方法的参数

 

      对于第一种变量,Java虚拟机会自动进行初始化。如果给出了初始值,则初始化为该初始值。如果没有给出,则把它初始化为该类型变量的默认初始值。

 

      int类型变量默认初始值为0

      float类型变量默认初始值为0.0f

      double类型变量默认初始值为0.0

      boolean类型变量默认初始值为false

      char类型变量默认初始值为0(ASCII码)

      long类型变量默认初始值为0

      所有对象引用类型变量默认初始值为null,即不指向任何对象。注意数组本身也是对象,所以没有初始化的数组引用在自动初始化后其值也是null。

 

      对于两种不同的类属性,static属性与instance属性,初始化的时机是不同的。instance属性在创建实例的时候初始化, static属性在类加载,也就是第一次用到这个类的时候初始化,对于后来的实例的创建,不再次进行初始化。这个问题会在以后的系列中进行详细讨论。

 

      对于第二种变量,必须明确地进行初始化。如果再没有初始化之前就试图使用它,编译器会抗议。如果初始化的语句在try块中或if块中,也必须要让它在第一次使用前一定能够得到赋值。也就是说,把初始化语句放在只有if块的条件判断语句中编译器也会抗议,因为执行的时候可能不符合if后面的判断条件,如此一来初始化语句就不会被执行了,这就违反了局部变量使用前必须初始化的规定。但如果在else块中也有初始化语句,就可以通过编译,因为无论如何,总有至少一条初始化语句会被执行,不会发生使用前未被初始化的事情。对于try-catch也是一样,如果只有在try块里才有初始化语句,编译部通过。如果在catch或finally里也有,则可以通过编译。总之,要保证局部变量在使用之前一定被初始化了。所以,一个好的做法是在声明他们的时候就初始化他们,如果不知道要出事化成什么值好,就用上面的默认值吧!

 

      其实第三种变量和第二种本质上是一样的,都是方法中的局部变量。只不过作为参数,肯定是被初始化过的,传入的值就是初始值,所以不需要初始化。

 

      问题六:instanceof是什么东东?

 

      instanceof是Java的一个二元操作符,和==,>,<是同一类东东。由于它是由字母组成的,所以也是Java的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回boolean类型的数据。举个例子:

 

      String s = "I AM an Object!";

      boolean isObject = s instanceof Object;

 

      我们声明了一个String对象引用,指向一个String对象,然后用instancof来测试它所指向的对象是否是Object类的一个实例,显然,这是真的,所以返回true,也就是isObject的值为True。

      instanceof有一些用处。比如我们写了一个处理账单的系统,其中有这样三个类:

 

      public class Bill

      public class PhoneBill extends Bill

      public class GasBill extends Bill

 

      在处理程序里有一个方法,接受一个Bill类型的对象,计算金额。假设两种账单计算方法不同,而传入的Bill对象可能是两种中的任何一种,所以要用instanceof来判断:

 

      public double calculate(Bill bill) {

           if (bill instanceof PhoneBill)

           if (bill instanceof GasBill)

           ...

      }

      这样就可以用一个方法处理两种子类。

 

      然而,这种做法通常被认为是没有好好利用面向对象中的多态性。其实上面的功能要求用方法重载完全可以实现,这是面向对象变成应有的做法,避免回到结构化编程模式。只要提供两个名字和返回值都相同,接受参数类型不同的方法就可以了:

 

      public double calculate(PhoneBill bill)

 

      public double calculate(GasBill bill)

 

      所以,使用instanceof在绝大多数情况下并不是推荐的做法,应当好好利用多态。

分享到:
评论

相关推荐

    java初学者细节资料

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

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

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

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

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

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

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

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

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

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

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

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

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

    Java多线程初学者指南

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

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

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

    疯狂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-Language-Specification-3rd-Edition

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

    Java毕业设计-JAVA打飞机游戏设计与实现(论文+源代码).rar

    本资源适用于Java初学者、游戏开发爱好者以及计算机专业的学生,可作为学习Java编程和游戏开发的实践项目。通过学习和实践,读者可以掌握Java游戏开发的基本技能,为进一步的学习和发展打下坚实的基础。

    [Java算法设计]-递归阶乘.java

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

    [Java算法-排序]冒泡排序.java

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

    [Java算法-排序]选择排序.java

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

Global site tag (gtag.js) - Google Analytics