My FAQ,最新最全的IT技术FAQ
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 未整理篇 | 技术讨论
  当前位置: > 程序开发 > 编程语言 > Java > 综合文章
这是怎么回事?
作者:未知 时间:2005-09-13 19:40 出处:ChinaUnix.net 责编:My FAQ
              摘要:这是怎么回事?

CLASSPATH 已经设定:CLASSPATH=.;C:\Program Files\Java\jdk1.5.0\lib\tools.jar;
代码如下:[code:1:0986166284]
public class test {
       public static void main(String[] args) {
String a = new String("hello");
System.out.println(a);
System.out.println(a.getClass().getName());
String b = (String)Class.forName("java.lang.String");
b = "class b";
System.out.println(b);
       }
}
[/code:1:0986166284]
为什么编译时总出现如下错误:
[code:1:0986166284]
C:\>javac test.java
test.java:6: inconvertible types
found   : java.lang.Class<capture of ?>
required: java.lang.String
                String b = (String)Class.forName("java.lang.String");
                                                ^
1 error
[/code:1:0986166284]
a.getClass().getName()得到的类名就是java.lang.String呀,这是怎么回事?望高手指教[/code]

 lilu_0608 回复于:2005-06-02 16:05:07
类型不对,而且不能被强制转换。把程序改成这样:
[code:1:eda4a8f8eb]
public class Test1 { 
      public static void main(String[] args) { 
   try{
          String a = new String("hello"); 
   System.out.println(a); 
   System.out.println(a.getClass().getName()); 
   String b = Class.forName("java.lang.String").toString(); 
   //b = "class b"; 
   System.out.println(b);
    }catch(ClassNotFoundException e) { }
      } 

[/code:1:eda4a8f8eb]
结果是:
[code:1:eda4a8f8eb]
hello
java.lang.String
class java.lang.String
[/code:1:eda4a8f8eb]

 idisc 回复于:2005-06-02 16:49:24
为什么加入try块他就行呢,而且能执行发生异常语句后面的语句呢?如这段代码
[code:1:13c0e57627]
public class test {
       public static void main(String[] args) {
               try {
                      Class.forName("java.lang.String");
                      System.out.println("hello");
               } catch (ClassNotFoundException e ){}
      }
}
[/code:1:13c0e57627]
不加try时无法编译,在forName处发生ClassNotFoundException 异常。
在加try之后System.out.println("hello");却能够执行,而catch 却没捕获到异常呢?请大虾少加解释

 sakulagi 回复于:2005-06-02 20:02:08
你的try{}里边的语句和你没加try时候的语句根本不一样,所以你后来写的这个加了try{}的代码没有异常

 yovn 回复于:2005-06-05 00:16:09
Class.forName()返回的是Class类型不是String类型,你如果想那样来创建String对象的话还得在Class上newInstance()然后转型为String

 perryhg 回复于:2005-06-05 00:49:00
看来你误会了Class.forName(...)的作用了,Class.forName是给你用来确保一个class被load到当前的classloader中,并且完成初始化以被后续是用的.最常用的地方是load jdbc驱动程序。

见文档:
public static Class<?> forName(String className)
                        throws ClassNotFoundException
Returns the Class object associated with the class or interface with the given string name. Invoking this method is equivalent to: 
  Class.forName(className, true, currentLoader)
 
where currentLoader denotes the defining class loader of the current class. 
For example, the following code fragment returns the runtime Class descriptor for the class named java.lang.Thread: 

   Class t = Class.forName("java.lang.Thread")
 
A call to forName("X") causes the class named X to be initialized. 

从你的代码看
[code:1:aa4d2e35ed]public class test {
      public static void main(String[] args) {
              try {
                     Class.forName("java.lang.String");
                     System.out.println("hello");
              } catch (ClassNotFoundException e ){}
     }
} [/code:1:aa4d2e35ed]

你似乎没有了解try/catch在程序中的作用,如果你定义的函数有throw,那么你调用这个函数的命令则必须用try/catch包裹,但是并不意味着一定会throw的,如果不发生exception,就不会执行catch部分的代码,这是正常的,只有发生了exception才需要执行catch的代码,目的是为了使得程序运行的时候得到更多的控制。有时候exception发生并不意味着致命错误,你仍然可以用一些办法使其继续工作。

举个例子吧:
比如,你要从数据库读取一些数据,然后合并到一个xml文件中去,其中一些项目,如果xml文件中存在,就不要去修改,如果不存在,则写入数据库读出来的部分。这个逻辑写成程序的时候应该是这样:
[code:1:aa4d2e35ed]try{
  //1. load database driver
  
  try{
     //2. read xml file
  }catch(xmlexception){
    //如果xml不存在,可以在这里创建一个空的schema,但是操作要继续下去
  }catch(writefileexception e){
    //如果无法写入文件,就把exception往上级处理程序抛,从而强行中断后面的更新程序
    throw e;
  }

  //3. 数据同步/更新
  //这里的程序就不会再受到不能写入的困扰了。
}catch(dbexception){
  //如果数据库无法访问,直接退出程序,不要继续了
}catch(writefileexception e){
  //这里处理不能写入的问题
}[/code:1:aa4d2e35ed]

这样的结构就把错误处理层次化了。在反复嵌套的调用结构中,如果每一级都要处理上面遗留下来的可能的错误,会导致程序越来越不受控制。有个非常典型的例子:程序到数据库读取一个数据,读出来一个null,这里面有几种可能:
1.这个数据本身就是null
2.sql语句出错
3.数据库没服务器没有启动
4.从客户端到服务器网络不通
5.客户端可用的socket用光,无法创建socket连接对方。
。。。

如果没有层次化exception处理,判断这些可能就变得非常困难,但是有了层次化的exception处理,你会得到确切的错误信息,并且错误不会被继续下去而产生更多的没有意义的错误,比如,如果连不上数据库服务器,就不要去执行sql操作的部分,应该直接跳出。这里不能简单地exit退出,如果数据库可能是个集群系统,你可能想尝试别的服务器,然后返回最终的结果呢?Exception就是帮助你来区分发生问题的层次,进而更有效的控制程序用简单的方法,更少的代码来达到目的的工具。

 yovn 回复于:2005-06-05 00:59:37
对于Class.forName()的作用我想做一些补充,如果只是确保一个类被loader到当前的classloader,那为什么不用Thread.getContextClassLoader() .loadClass("clasName")???
Class.forName()不仅load class而且还保证resolve这个class,包括常量池解析,类初始化。。。这样JDBC驱动使用这个方法,才能保证
类里的静态方法执行,一般驱动类的静态方法会向  DriverManager注册自己,如果用classloader.load()就不一定会resolve这个class,也就不能保证注册驱动类!

 perryhg 回复于:2005-06-05 01:10:04
谢谢yovn侠客的补充!

 idisc 回复于:2005-06-08 11:08:40
感谢各位的精彩解答,由于初涉java,一些地方了解得不算太清楚,望各位以后多加指教

 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 myfaq.com.cn All rights reserved. www.myfaq.com.cn 版权所有