| 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,一些地方了解得不算太清楚,望各位以后多加指教
|