`

java解惑你知多少(六)

    博客分类:
  • Java
 
阅读更多

41. instanceof与转型

Java代码  收藏代码
  1. System.out.println(null instanceof String);//false  
  2. System.out.println(new Object() instanceof String);//false  
  3. //编译能通过  
  4. System.out.println((Object) new Date() instanceof String);//false  
  5. //!!程序不具有实际意义,但编译时不能通过  
  6. //!!System.out.println(new Date() instanceof String);  
  7. //!!运行时抛ClassCastException,这个程序没有任何意义,但可以编译  
  8. //!!System.out.println((Date) new Object());  

null可以表示任何引用类型,但是instanceof操作符被定义为在其左操作数为null时返回false。

 

如果instanceof告诉你一个对象引用是某个特定类型的实例,那么你就可以将其转型为该类型,并调用该类型的方法

,而不用担心会抛出ClassCastException或NullPointerException异常。

 

instanceof操作符有这样的要求:左操作数要是一个对象的或引用,右操作数是一个引用类型,并且这两个操作数的

类型是要父子关系(左是右的子类,或右是左的子类都行),否则编译时就会出错。


42. 父类构造器调用已重写的方法

Java代码  收藏代码
  1. public class P {  
  2.  private int x, y;  
  3.  private String name;  
  4.   
  5.  P(int x, int y) {  
  6.   this.x = x;  
  7.   this.y = y;  
  8.   // 这里实质上是调用子类被重写的方法  
  9.   name = makeName();  
  10.  }  
  11.   
  12.  protected String makeName() {  
  13.   return "[" + x + "," + y + "]";  
  14.  }  
  15.   
  16.  public String toString() {  
  17.   return name;  
  18.  }  
  19.   
  20. }  
  21.   
  22. class S extends P {  
  23.  private String color;  
  24.   
  25.  S(int x, int y, String color) {  
  26.   super(x, y);  
  27.   this.color = color;  
  28.  }  
  29.   
  30.  protected String makeName() {  
  31.   return super.makeName() + ":" + color;  
  32.  }  
  33.   
  34.  public static void main(String[] args) {  
  35.   System.out.println(new S(12"red"));// [1,2]:null  
  36.  }  
  37. }  

 

在一个构造器调用一个已经被其子类重写了的方法时,可能会出问题:如果子类重写的方法要访问的子类的域还未初

始化,因为这种方式被调用的方法总是在实例初始化之前执行。要想避免这个问题,就千万不要在父类构造器中调用

已重写的方法。


43. 静态域与静态块的初始顺序

Java代码  收藏代码
  1. public class T {  
  2.  public static int i = prt();  
  3.  public static int y = 1;  
  4.  public static int prt() {  
  5.   return y;  
  6.  }  
  7.   
  8.  public static void main(String[] args) {  
  9.   System.out.println(T.i);// 0  
  10.  }  
  11. }  

上面的结果不是1,而是0,为什么?

 

类初始化是按照静态域或静态块在源码中出现的顺序去执行这些静态初始器的(即谁先定义,就先初始化谁),上现程序中由于i先于y声明,所以先初始化i,但由于i初始化时需要由y来决定,此时y又未初始化,实为初始前的值0,所以i的最后结果为0。


44. 请使用引用类型调用静态方法

Java代码  收藏代码
  1. public class Null {  
  2.  public static void greet() {  
  3.   System.out.println("Hello world!");  
  4.  }  
  5.   
  6.  public static void main(String[] args) {  
  7.   ((Null) null).greet();  
  8.  }  
  9. }  

上面程序运行时不会打印NullPointerException异常,而是输出"Hello world!",关键原因是:调用静态方法时将忽略前面的调用对象或表达示,只与对象或表达式计算结果的类型有关。

 

在调用静态方法时,一定要使用类去调用,或是静态导入后直接使用。


45. 循环中的不能声明局部变量

Java代码  收藏代码
  1. for (int i = 0; i < 1; i++)   
  2.  Object o ; //!! 编译不能通过  
  3.   
  4. for (int i = 0; i < 1; i++)   
  5.  Object o = new Object(); //!! 编译不能通过  

 

一个本地变量声明看起来像是一条语句,但是从技术上来说不是。

 

Java语言规范不允许一个本地变量声明语句作为一条语句在for、while或do循环中重复执行。

 

一个本地变量声明作为一条语句只能直接出现在一个语句块中(一个语句块是由一对花 括号以及包含在这对花括号中的语句和声明构成的):

Java代码  收藏代码
  1. for (int i = 0; i < 1; i++) {  
  2.  Object o = new Object(); // 编译OK  
  3. }  

 

46. 内部类反射

Java代码  收藏代码
  1. public class Outer {  
  2.  public class Inner {  
  3.   public String toString() {  
  4.    return "Hello world";  
  5.   }  
  6.  }  
  7.  public void getInner() {  
  8.   try {  
  9.    // 普通方式创建内部类实例  
  10.    System.out.println(new Outer().new Inner());// Hello world  
  11.    //!! 反射创建内部类,抛异常:java.lang.InstantiationException:Outer$Inner  
  12.    System.out.println(Inner.class.newInstance());  
  13.   } catch (Exception e) {  
  14.   }  
  15.  }  
  16.  public static void main(String[] args) {  
  17.    new Outer().getInner();  
  18.  }  
  19. }  

上面因为构造内部类时外部类实例不存在而抛异常。

 

一个非静态的嵌套类的构造器,在编译的时候会将一个隐藏的参数作为它的第一个参数,这个参数表示它的直接外围实例。如果使用反射创建内部类,则要传递个隐藏参数的唯一方法就是使用java.lang.reflect.Constructor:

Java代码  收藏代码
  1. Constructor c = Inner.class.getConstructor(Outer.class);//获取带参数的内部类构造函数  
  2. System.out.println(c.newInstance(Outer.this));//反射时还需传进外围类  
分享到:
评论

相关推荐

    java解惑(+Java 解惑你知多少)

    你认为自己了解Java多少?你是个爱琢磨的代码侦探吗?你是否曾经花费数天时间去追踪一个由Java或其类库的陷阱和缺陷而导致的bug?你喜欢智力测验吗?本书正好适合你!.. Bloch和Gafter继承了Effective Jaya一书的传统,...

    java 解惑 java 解惑 java 解惑

    java 解惑 java 解惑 java 解惑 java 解惑 java 解惑 java 解惑

    Java解惑(中文版)_java_java解惑_solve65p_

    《Java解惑(中文版)》是一本专为Java初学者设计的学习资料,旨在帮助读者解答在学习Java过程中遇到的各种困惑。"solve65p"可能代表这本书包含65个问题或主题,每个都深入浅出地进行了讲解,旨在解决初学者在编程...

    Java PUZZLE Java 解惑

    Java PUZZLE Java 解惑 Java PUZZLE Java 解惑 Java PUZZLE Java 解惑Java PUZZLE Java 解惑 Java PUZZLE Java 解惑 Java PUZZLE Java 解惑

    Java解惑 中文版

    《Java解惑中文版》是一本专为Java程序员设计的指南,旨在帮助读者解决在编程过程中遇到的各种问题,提升程序的健壮性。本书深入浅出地探讨了Java语言的核心概念、常见疑惑以及最佳实践,旨在使开发者能够编写出更...

    JAVA 解惑 java经典

    "JAVA解惑"的主题针对的是Java学习过程中遇到的一些常见问题和难点,旨在帮助开发者深入理解和解决这些问题。以下是基于这个主题和描述可能涵盖的一些关键知识点: 1. **Java基础**:这可能包括变量、数据类型、...

    Java解惑.pdf

    这份“Java解惑.pdf”文档很可能包含了解决Java开发者在编程过程中遇到的常见问题和困惑的详细解答。以下是可能涵盖的一些Java相关知识点: 1. **基础语法**:Java的基础语法包括变量、数据类型、运算符、流程控制...

    "java解惑" PDF版本

    "java解惑" PDF版本

    java解惑 PDF版

    文档《java解惑 PDF版》中列举了95个这样的谜题,每个谜题都旨在帮助开发者理解并纠正一些常见的错误理解。以下是根据提供的部分内容解析的几个相关知识点。 ### 表达式谜题与取余操作符(%)的行为 在Java中,...

    Java解惑 布洛克 著;陈昊鹏 译

    《Java解惑》 布洛克 著;陈昊鹏 译 扫描清晰带目录,仅供参阅,请支持正版

    JAVA解惑.pdf

    《JAVA解惑》这本书主要针对Java编程中遇到的各种常见问题和困惑进行了解答,旨在帮助开发者深入理解Java语言,提高编程技巧。以下是一些关键的知识点解析: 1. **异常处理**:Java中的异常处理是通过try-catch-...

    4,JAVA解惑 高清PDF 下载

    《JAVA解惑》是Java开发者领域的一本经典著作,它被广大...总之,《JAVA解惑》是一本涵盖了Java核心知识点、实战技巧和高级特性的宝典,无论你是Java新手还是老手,都能从中受益匪浅,解决你在Java编程中的种种疑惑。

    java解惑java解惑java解惑

    "Java解惑"这个主题,显然旨在帮助开发者解决他们在学习和实践中遇到的问题。在Java的世界里,疑惑可能涵盖语法、类库、框架、并发、内存管理等多个方面。下面,我们将深入探讨一些常见的Java解惑知识点。 1. **...

    java解惑 for all javaer

    讲述如何在程序中避免程序缺陷和程序陷阱的,解惑的过程中,介绍了一些Java编程语言中许多不易被掌握的知识点,其阅读价值非常高,适合具有Java知识的学习者和有编程经验的Java程序员阅读。

    JAVA解惑.pfd

    JAVA解惑

    java解惑(包括pdf和答案)

    "java解惑"这个主题旨在帮助初学者理解和解决在学习Java过程中遇到的问题,通过实例来深入浅出地讲解Java的基础知识,同时也强调了实用技巧和注意事项。 "Java解惑"的资料可能包含了两部分:`.chm`和`.pdf`格式的...

    Java解惑(中文).pdf

    《Java解惑(中文)》是一本专门为Java开发者编写的指南书籍,旨在解决在实际编程过程中遇到的各种疑惑和难题。本书以中文语言呈现,使得国内的Java程序员能够更轻松地理解并应用其中的知识。通过阅读这本书,读者...

    Java解惑(中文).pdf

    "Java解惑(中文).pdf"这份文档很显然是为了帮助Java开发者解决他们在编程过程中遇到的一些常见困惑和误解。这份高清版、文字版的资料很可能包含了深入浅出的解释和实例分析,以中文的形式呈现,使得国内开发者更容易...

Global site tag (gtag.js) - Google Analytics