`

Java 解惑知多少六

阅读更多
41. instanceof与转型
System.out.println(null instanceof String);//false  
System.out.println(new Object() instanceof String);//false  
//编译能通过  
System.out.println((Object) new Date() instanceof String);//false  
//!!程序不具有实际意义,但编译时不能通过  
//!!System.out.println(new Date() instanceof String);  
//!!运行时抛ClassCastException,这个程序没有任何意义,但可以编译  
//!!System.out.println((Date) new Object());  

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

如果instanceof告诉你一个对象引用是某个特定类型的实例,那么你就可以将其转型为该类型,并调用该类型的方法
,而不用担心会抛出ClassCastException或NullPointerException异常。

instanceof操作符有这样的要求:左操作数要是一个对象的或引用,右操作数是一个引用类型,并且这两个操作数的
类型是要父子关系(左是右的子类,或右是左的子类都行),否则编译时就会出错。
42. 父类构造器调用已重写的方法
public class P {  
 private int x, y;  
 private String name;  
  
 P(int x, int y) {  
  this.x = x;  
  this.y = y;  
  // 这里实质上是调用子类被重写的方法  
  name = makeName();  
 }  
  
 protected String makeName() {  
  return "[" + x + "," + y + "]";  
 }  
  
 public String toString() {  
  return name;  
 }  
  
}  
  
class S extends P {  
 private String color;  
  
 S(int x, int y, String color) {  
  super(x, y);  
  this.color = color;  
 }  
  
 protected String makeName() {  
  return super.makeName() + ":" + color;  
 }  
  
 public static void main(String[] args) {  
  System.out.println(new S(1, 2, "red"));// [1,2]:null  
 }  
}  

在一个构造器调用一个已经被其子类重写了的方法时,可能会出问题:如果子类重写的方法要访问的子类的域还未初
始化,因为这种方式被调用的方法总是在实例初始化之前执行。要想避免这个问题,就千万不要在父类构造器中调用
已重写的方法。
43. 静态域与静态块的初始顺序
public class T {  
 public static int i = prt();  
 public static int y = 1;  
 public static int prt() {  
  return y;  
 }  
  
 public static void main(String[] args) {  
  System.out.println(T.i);// 0  
 }  
}  

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

类初始化是按照静态域或静态块在源码中出现的顺序去执行这些静态初始器的(即谁先定义,就先初始化谁),上现程序中由于i先于y声明,所以先初始化i,但由于i初始化时需要由y来决定,此时y又未初始化,实为初始前的值0,所以i的最后结果为0。
44. 请使用引用类型调用静态方法
public class Null {  
 public static void greet() {  
  System.out.println("Hello world!");  
 }  
  
 public static void main(String[] args) {  
  ((Null) null).greet();  
 }  
}  

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

在调用静态方法时,一定要使用类去调用,或是静态导入后直接使用。
45. 循环中的不能声明局部变量
for (int i = 0; i < 1; i++)   
 Object o ; //!! 编译不能通过  
  
for (int i = 0; i < 1; i++)   
 Object o = new Object(); //!! 编译不能通过  

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

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

一个本地变量声明作为一条语句只能直接出现在一个语句块中(一个语句块是由一对花 括号以及包含在这对花括号中的语句和声明构成的):
for (int i = 0; i < 1; i++) {  
 Object o = new Object(); // 编译OK  
} 

46. 内部类反射
public class Outer {  
 public class Inner {  
  public String toString() {  
   return "Hello world";  
  }  
 }  
 public void getInner() {  
  try {  
   // 普通方式创建内部类实例  
   System.out.println(new Outer().new Inner());// Hello world  
   //!! 反射创建内部类,抛异常:java.lang.InstantiationException:Outer$Inner  
   System.out.println(Inner.class.newInstance());  
  } catch (Exception e) {  
  }  
 }  
 public static void main(String[] args) {  
   new Outer().getInner();  
 }  
}  

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

一个非静态的嵌套类的构造器,在编译的时候会将一个隐藏的参数作为它的第一个参数,这个参数表示它的直接外围实例。如果使用反射创建内部类,则要传递个隐藏参数的唯一方法就是使用java.lang.reflect.Constructor:
Constructor c = Inner.class.getConstructor(Outer.class);//获取带参数的内部类构造函数  
System.out.println(c.newInstance(Outer.this));//反射时还需传进外围类  


ref:http://jiangzhengjun.iteye.com/blog/652762
分享到:
评论
1 楼 xiangxm 2012-10-09  
学习了。

相关推荐

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

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

    Java 解惑(细致实用)

    本篇将基于“Java解惑”这一主题,详细探讨Java中的常见问题、易错点以及需要注意的细节。 1. **内存管理与垃圾回收** - Java的自动内存管理机制是通过垃圾回收(Garbage Collection, GC)来实现的。理解如何工作...

    java解惑99

    在“java解惑99”这个主题中,我们可以深入探讨一系列关于Java编程的常见问题和解决方案。这个压缩包文件包含了作者个人对Java编程难题的源码解析和分析,旨在帮助开发者们解决他们在学习和实践中遇到的困难。让我们...

    Java解惑.pdf

    ### Java解惑知识点详解 #### 一、表达式谜题:判断奇数的正确方法 在探讨本书提及的第一个“表达式谜题”时,我们首先遇到了一个用来判断一个整数是否为奇数的方法: ```java public static boolean isOdd(int i...

    Java解惑(中文)

    ### Java解惑:常见误区与解答 #### 一、判断奇数的方法问题 **知识点概述:** 本节讨论了一个常见的编程误区,即如何正确判断一个整数是否为奇数。通常,开发人员会认为可以通过模运算(%)来判断一个整数是否能...

    一本关于java不错的书

    《Java解惑》是一本专为初学者设计的Java编程指南,它旨在帮助读者深入理解Java语言的基础概念和核心特性,从而轻松入门并逐步提升编程技能。这本书涵盖了从基本语法到高级特性的全面内容,是Java学习者的理想伙伴。...

    Java Web编程宝典-十年典藏版.pdf.part2(共2个)

    第3篇为项目实战篇,主要包括讯友联系人管理模块、播客视频管理模块、博客管理模块、明日知道论坛管理模块等4个小型项目:第4篇为商业系统篇,主要包括一个大型的商业项目,即天下淘网上购物商城系统。 《Java Web...

    java版IPMSG 含源码(在JAR包里)

    java 仿IPMSG程序,还有些小问题. 1.文件传输速度太慢,可以创建发送和接收缓存提高传输速度,最简单的办法就是加大UDP包大小,设置MyPacket.java 文件里变量...但是丢包的原因一直不太明白,如有达人知道请留言解惑.谢了

    大学计算机专业书籍推荐.pdf

    * Java 解惑:昊斯特曼Java 解惑 操作系统: * LINUX 教程:布洛克LINUX 教程 :Windows 用户转向 Linux的 12 个步骤 * Linux 私房菜:米勒鸟哥的 Linux私房菜 * 现代操作系统:鸟哥现代操作系统 * 操作系统 - 内核...

    oracle执行调度百度

    2. "JAVA面试题解惑系列.pdf":虽然这个文件名与Oracle执行调度直接关联性不大,但考虑到Java在企业级应用开发中的广泛使用,特别是在与Oracle数据库交互时,这份PDF可能包含了一些关于Java如何连接、操作Oracle...

    一个简单的购物系统项目

    压缩包内的文件"jsp实验20101013.doc"可能是关于JSP的实验指导或教程,"《IT学生解惑真经》.doc"可能是包含更多编程知识的资料,而"eshop1", "eshop2", "eshop3"很可能是项目的不同版本或模块,"096442"可能是某个...

Global site tag (gtag.js) - Google Analytics