我不是科班出生的,所以想操作系统和体系结构之类的课都是自学的,后来在遇到指针和句柄这样的问题时的确也很迷惑。我在重读Thinking in Java时就花了好多功夫去找相关的资料,总算弄明白点,试着来回答下:我们知道,操作系统在执行一段程序代码时,一方面系统会读进代码段,另一方面系统还需要给这段代码分配一块内存,用来存放执行代码需要的变量。比如代码里用到一个int,那么操作系统就在这片内存中创建一个int变量,如果是要new一个String,系统就创建一个字符串对象。这块内存的大小由操作系统决定,如果不够用了,操作系统会在增配内存。程序执行完毕,这段内存就会被释放掉。在TIJ第二章《Everything is an Object》里列举了6种存储数据的地方:
Registers、The stack、The heap、Static storage、Constant storage、Non-RAM storage。“引用——reference”是一种指向某块内存空间的变量,它存储了内存空间的地址,我们可以通过reference找到这个地址对应的内存。我对照看的一些E文书和翻译版的,发现有把refrence翻译成句柄的,一般来说C/C++中refrence就翻译成指针,而在java中refrence就翻译成句柄。这涉及到C++和JAVA对内存操作的不同。C++的内存处理方式是栈式的,栈内存是一个线性空间,操作方式是在栈头压入或弹出内存块,C++内存的申请和释放都是由程序控制的,这种方式操作内存速度块,缺点就是不够安全。C++中的指针变量和指针所指的用来存放数据的内存块都是在栈中的,如:
string *stringPtr1 = new string;
那么在内存里就增加了一个指针变量和一个string变量,指针变量的值就是string变量的地址。如果程序结束时不delete stringPtr1,那么系统只会回收指针变量,而那个string变量系统会认为还在用,于是这块内存就漏掉了。而在java里,程序的内存是同时在栈里和堆里的。像int之类的原型变量、函数的参数、句柄变量都是放在栈里的,而对象是放在堆里的。如:
String str = new String();
此时栈里增加了一个String句柄变量,而堆里增加了一个String对象。栈里的这个句柄变量指向堆里的这个String变量。当使用完毕后,栈里的内存全部清除,而堆里的这个String对象就依靠“垃圾收集”机制来回收。指针和句柄、引用的不同是:句柄和引用一般都是指向对象的,像C++里也有句柄的概念,就是指那些指向文件对象、窗体对象什么的指针;而指针是可以指向诸如int、char之类的变量的,它就是指向某个内存地址,而不管所指的内存包含什么内容。还有一点是我不太清楚的,就是句柄变量里是不是含有类型信息?
我试了
Object o = null;
String str = (String)o;
程序不报错,但是
Object o = new Object();
String str = (String)o;
就会报java.lang.ClassCastException错误。

解决方案 »

  1.   

    一楼的说的问题所报的错是在输出的时候才会有的
    如果不加System.out.println(str);的话是不会报错的
    这个异常文档给的解释是:Thrown to indicate that the code has attempted to cast an object to a subclass of which it is not an instance。也就是试图将一对象转换为没有实例的子类时的异常
    也就是说Object o=null中null并不是表示空的意思,应该是一组字符
      

  2.   

    还有一点是我不太清楚的,就是句柄变量里是不是含有类型信息?
    我试了
    Object o = null;
    String str = (String)o;
    程序不报错,但是
    Object o = new Object();
    String str = (String)o;
    就会报java.lang.ClassCastException错误。这个是肯定的了。
    null可以赋值给任何对象的呀
    new的话生成了一个Object对象,当然不可以转化为String了
      

  3.   

    Object o = null;
    String str = (String)o;我认为o成了str的别名。而不是“也就是说Object o=null中null并不是表示空的意思,应该是一组字符”
    第二种为什么错了?object虽然是所有类的基础,但是“(String)o”向下转型的时候(toString)没有对应的实例。我的认为引用就是指针的“阉割”。少了直接对内存操作的功能。
      

  4.   

    new的话生成了一个Object对象,当然不可以转化为String了不是这个原因。要注意下向转型的情况。Thrown to indicate that the code has attempted to cast an object to a subclass of which it is not an instance. For example, the following code generates a ClassCastException:
          Object x = new Integer(0);
         System.out.println((String)x);
    这是jdk帮助上的一个典型例子。和搂住得没有什么区别。