初拾Java(问题二:缺类异常,无法编译)

昨天,在看JSP页面包含的元素(JSP指令,生命,表达式,动作等)时,拷贝了一个别人的例子来在Myeclipse里运行,结果出现了如下的缺类错误:

多调试两次也会出现如下无法编译的错误:

具体代码如下:

 1 <%@ page language="java" import="java.util.Calendar" pageEncoding="UTF-8"%>
 2 <%! 
 3     String  getHello(String name)
 4     {
 5         return "Hello" +name + "!";    
 6     }
 7 %>
 8 
 9 <% Calendar now = new Calendar.getInstance(); %>
10 
11 <html>
12   <head> 
13     
14     <title>hello TwoTwo</title>
15  
16   </head> 
17   <body>
18        <h1>
19            <%=getHello("Bonnie") %>
20        <h1>
21            <%
22            if(now.get(Calendar.AM_PM == Calendar.AM))
23                {  
24                    早上好!
25                }else{ 
26                    下午好!
27                }      %>
28   
29   </body>
30 </html>
View Code

分析了上面两个错误原因发现,他的意思是我没有引入java.util.Calendar这个类,才导致了后面使用时找不到,所以报出编译不通过缺类错误,可一看代码我的确是引用了呀,再去百度一下其他可能相关的原因,有说可能是编码不一致,所以就去右击该JSP文件,找到属性然后去修改他的编码和d代码中的一致,再去试着运行,还是不行,同样的问题。然后再看看代码中的不同之处,我是后面自己创建了一个JSP页面,所以开头是:

<%@ page language="java" import="java.util.Calendar" pageEncoding="UTF-8"%>
View Code

而原文中的开头是:

<%@page contentType="text/html;charset=GBK" language="java" import="java.util.Calendar"%>
View Code

对比不同之处就是一个使用了属性:pageEncoding,另一个使用了属性:contentType,所以又去百度了这两者的区别:

关于JSP页面中的pageEncodingcontentType两种属性的区别:

pageEncoding是jsp文件本身的编码,contentType的charset是指服务器发送给客户端时的内容编码。JSP要经过两次的“编码”,第一阶段会用pageEncoding,第二阶段会用utf-8至utf-8,第三阶段就是由Tomcat出来的网页,用的是contentType。

第一阶段是jsp编译成java

它会根据pageEncoding的设定读取jsp,结果是由指定的编码方案翻译成统一的UTF-8 JAVA源码(即.java),如果pageEncoding设定错了,或没有设定,出来的就是中文乱码。

第二阶段是由JAVAC的JAVA源码至java byteCode的编译

不论JSP编写时候用的是什么编码方案,经过这个阶段的结果全部是UTF-8的encoding的java源码。

JAVAC用UTF-8的encoding读取java源码,编译成UTF-8 encoding的二进制码(即.class),这是JVM对常数字串在二进制码(java encoding)内表达的规范。

第三阶段是Tomcat(或其的application container)载入和执行阶段二来的

JAVA二进制码输出的结果,也就是在客户端见到的,这时隐藏在阶段一和阶段二的参数contentType就发挥了功效contentType,pageEncoding 和contentType的预设都是 ISO8859-1. 而随便设定了其中一个, 另一个就跟着一样了(TOMCAT4.1.27是如此). 但这不是绝对的, 这要看各自JSPC的处理方式. 而pageEncoding不等于contentType, 更有利亚洲区的文字 CJKV系JSP网页的开发和展示, (例pageEncoding=GB2312 不等于 contentType=utf-8)。

jsp文件不像.java,.java 在被编译器读入的时候默认采用的是操作系统所设定的locale所对应的编码,比如中国大陆就是GBK,台湾就是BIG5或者MS950。而一般我们不管是在记事本还是在ue中写代码,如果没有经过特别转码的话,写出来的都是本地编码格式的内容。所以编译器采用的方法刚好可以让虚拟机得到正确的资料。但是jsp文件不是这样,它没有这个默认转码过程,但是指定了pageEncoding就可以实现正确转码了。

为了解决无法编译的情况,还是将两者设置的一样吧,所以就都使用了可以编译成功的contentType=“text/html;charset=GBK”,再去编译运行,还是报同样的错误,晕死!!!

排除了这个原因,再往其他方向考虑。

换个思路后想着,是因为在编译的时候缺类导致的错误,那么,JSP编译后会变成什么呢?再次去网上寻找答案,有人说JSP背后的技术是servlet,当一个请求访问JSP文件时,web服务器把JSP翻译成servlet的java文件,再由编译器把servlet的java文件编译成class文件,最后由解释器解释执行。这样说来,JSP要经过两次编译,编译后会有.java文件和.class文件生成,那么,生成后的这两类文件存放在哪里呢?因为我用的是Myeclipse+Tomcat,所以就可以在Tomcat的安装目录下找到编译后的文件(URL:D:\apache-tomcat-7.0.70\work\Catalina\localhost\J2eeTest\org\apache\jsp)。

随后,我又去对比了一下所生成的文件,运行通过的有.java + .class文件,不能运行的只有.java文件,对比一下发现,原来首次编译就是把JSP语言转换成java语言,而一对比我就被自己给蠢cry了。之所以会缺类是因为我按照习惯看到类Calendar就来个new一个实例(Calendar now =new Calendar.getInstance(); )。

最后,虽然问题很low,但感谢遇到的问题,让我自己在慢慢查找问题的过程中成长!

 

参考:http://blog.sina.com.cn/s/blog_6a61ea1c0101e26k.html

 

posted @ 2017-02-10 13:14  Bonnieh  阅读(538)  评论(0编辑  收藏  举报