﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-</title><link>http://www.blogjava.net/shangaijun/</link><description>性格决定命运，气度影响格局</description><language>zh-cn</language><lastBuildDate>Mon, 18 May 2026 14:50:55 GMT</lastBuildDate><pubDate>Mon, 18 May 2026 14:50:55 GMT</pubDate><ttl>60</ttl><item><title>Java语言异常处理的陋习展播</title><link>http://www.blogjava.net/shangaijun/archive/2007/11/08/159032.html</link><dc:creator>尚爱军</dc:creator><author>尚爱军</author><pubDate>Thu, 08 Nov 2007 02:45:00 GMT</pubDate><guid>http://www.blogjava.net/shangaijun/archive/2007/11/08/159032.html</guid><wfw:comment>http://www.blogjava.net/shangaijun/comments/159032.html</wfw:comment><comments>http://www.blogjava.net/shangaijun/archive/2007/11/08/159032.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shangaijun/comments/commentRss/159032.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shangaijun/services/trackbacks/159032.html</trackback:ping><description><![CDATA[<span style="font-family: Georgia;">你觉得自己是一个Java专家吗？是否肯定自己已经全面掌握了Java的异常处理机制？在下面这段代码中，你能够迅速找出异常处理的六个问题吗？
<table bgcolor="#cccccc" cellpadding="0" cellspacing="1" width="80%">
    <tbody>
        <tr>
            <td bgcolor="#f2f2f2">
            <pre>1 OutputStreamWriter out = ... <br />
            2 java.sql.Connection conn = ... <br />
            3 try { // ⑸ <br />
            4 　Statement stat = conn.createStatement(); <br />
            5 　ResultSet rs = stat.executeQuery( <br />
            6 　　"select uid, name from user"); <br />
            7 　while (rs.next()) <br />
            8 　{ <br />
            9 　　out.println("ID：" + rs.getString("uid") // ⑹ <br />
            10 　　　"，姓名：" + rs.getString("name")); <br />
            11 　} <br />
            12 　conn.close(); // ⑶ <br />
            13 　out.close(); <br />
            14 } <br />
            15 catch(Exception ex) // ⑵ <br />
            16 { <br />
            17 　ex.printStackTrace(); //⑴，⑷ <br />
            18 } <br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<p>　　作为一个Java程序员，你至少应该能够找出两个问题。但是，如果你不能找出全部六个问题，请继续阅读本文。</p>
<p>　　本文讨论的不是Java异常处理的一般性原则，因为这些原则已经被大多数人熟知。我们要做的是分析各种可称为&#8220;反例&#8221;（anti-pattern）的违背优秀编码规范的常见坏习惯，帮助读者熟悉这些典型的反面例子，从而能够在实际工作中敏锐地察觉和避免这些问题。</p>
<p>　　反例之一：丢弃异常</p>
<p>　　代码：15行-18行。</p>
<p>　　这段代码捕获了异常却不作任何处理，可以算得上Java编程中的杀手。从问题出现的频繁程度和祸害程度来看，它也许可以和C/C++程序的一个
恶名远播的问题相提并论？？不检查缓冲区是否已满。如果你看到了这种丢弃（而不是抛出）异常的情况，可以百分之九十九地肯定代码存在问题（在极少数情况
下，这段代码有存在的理由，但最好加上完整的注释，以免引起别人误解）。</p>
<p>　　这段代码的错误在于，异常（几乎）总是意味着某些事情不对劲了，或者说至少发生了某些不寻常的事情，我们不应该对程序发出的求救信号保持沉默和
无动于衷。调用一下printStackTrace算不上&#8220;处理异常&#8221;。不错，调用printStackTrace对调试程序有帮助，但程序调试阶段结束
之后，printStackTrace就不应再在异常处理模块中担负主要责任了。</p>
<p>　　丢弃异常的情形非常普遍。打开JDK的ThreadDeath类的文档，可以看到下面这段说明：&#8220;特别地，虽然出现ThreadDeath是一
种&#8216;正常的情形&#8217;，但ThreadDeath类是Error而不是Exception的子类，因为许多应用会捕获所有的Exception然后丢弃它不再
理睬。&#8221;这段话的意思是，虽然ThreadDeath代表的是一种普通的问题，但鉴于许多应用会试图捕获所有异常然后不予以适当的处理，所以JDK把
ThreadDeath定义成了Error的子类，因为Error类代表的是一般的应用不应该去捕获的严重问题。可见，丢弃异常这一坏习惯是如此常见，它
甚至已经影响到了Java本身的设计。</p>
<p>　　那么，应该怎样改正呢？主要有四个选择：</p>
<p>　　1、处理异常。针对该异常采取一些行动，例如修正问题、提醒某个人或进行其他一些处理，要根据具体的情形确定应该采取的动作。再次说明，调用printStackTrace算不上已经&#8220;处理好了异常&#8221;。</p>
<p>　　2、重新抛出异常。处理异常的代码在分析异常之后，认为自己不能处理它，重新抛出异常也不失为一种选择。</p>
<p>　　3、把该异常转换成另一种异常。大多数情况下，这是指把一个低级的异常转换成应用级的异常（其含义更容易被用户了解的异常）。</p>
<p>　　4、不要捕获异常。</p>
<p>　　结论一：既然捕获了异常，就要对它进行适当的处理。不要捕获异常之后又把它丢弃，不予理睬。</p>
<p>　　反例之二：不指定具体的异常</p>
<p>　　代码：15行。</p>
<p>　　许多时候人们会被这样一种&#8220;美妙的&#8221;想法吸引：用一个catch语句捕获所有的异常。最常见的情形就是使用catch（Exception ex）语句。但实际上，在绝大多数情况下，这种做法不值得提倡。为什么呢？</p>
<p>　　要理解其原因，我们必须回顾一下catch语句的用途。catch语句表示我们预期会出现某种异常，而且希望能够处理该异常。异常类的作用就是
告诉Java编译器我们想要处理的是哪一种异常。由于绝大多数异常都直接或间接从java.lang.Exception派生，catch
（Exception ex）就相当于说我们想要处理几乎所有的异常。</p>
<p>　　再来看看前面的代码例子。我们真正想要捕获的异常是什么呢？最明显的一个是SQLException，这是JDBC操作中常见的异常。另一个可
能的异常是IOException，因为它要操作OutputStreamWriter.显然，在同一个catch块中处理这两种截然不同的异常是不合适
的。如果用两个catch块分别捕获SQLException和IOException就要好多了。这就是说，catch语句应当尽量指定具体的异常类
型，而不应该指定涵盖范围太广的Exception类。</p>
<p>　　另一方面，除了这两个特定的异常，还有其他许多异常也可能出现。例如，如果由于某种原因，executeQuery返回了null，该怎么办？
答案是让它们继续抛出，即不必捕获也不必处理。实际上，我们不能也不应该去捕获可能出现的所有异常，程序的其他地方还有捕获异常的机会？？直至最后由
JVM处理。</p>
<p>　　结论二：在catch语句中尽可能指定具体的异常类型，必要时使用多个catch.不要试图处理所有可能出现的异常。</p>
<p>　　反例之三：占用资源不释放</p>
<p>　　代码：3行-14行。</p>
<p>　　异常改变了程序正常的执行流程。这个道理虽然简单，却常常被人们忽视。如果程序用到了文件、Socket、JDBC连接之类的资源，即使遇到了异常，也要正确释放占用的资源。为此，Java提供了一个简化这类操作的关键词finally.</p>
<p>　　finally是样好东西：不管是否出现了异常，Finally保证在try/catch/finally块结束之前，执行清理任务的代码总是有机会执行。遗憾的是有些人却不习惯使用finally.</p>
<p>　　当然，编写finally块应当多加小心，特别是要注意在finally块之内抛出的异常？？这是执行清理任务的最后机会，尽量不要再有难以处理的错误。</p>
<p>　　结论三：保证所有资源都被正确释放。充分运用finally关键词。</p>
<p>　　反例之四：不说明异常的详细信息</p>
<p>　　代码：3行-18行。</p>
<p>　　仔细观察这段代码：如果循环内部出现了异常，会发生什么事情？我们可以得到足够的信息判断循环内部出错的原因吗？不能。我们只能知道当前正在处理的类发生了某种错误，但却不能获得任何信息判断导致当前错误的原因。</p>
<p>printStackTrace的堆栈跟踪功能显示出程序运行到当前类的执行流程，但只提供了一些最基本的信息，未能说明实际导致错误的原因，同时也不易解读。
</p>
<p>　　因此，在出现异常时，最好能够提供一些文字信息，例如当前正在执行的类、方法和其他状态信息，包括以一种更适合阅读的方式整理和组织printStackTrace提供的信息。</p>
<p>　　结论四：在异常处理模块中提供适量的错误原因信息，组织错误信息使其易于理解和阅读。</p>
<p>　　反例之五：过于庞大的try块</p>
<p>　　代码：3行-14行。</p>
<p>　　经常可以看到有人把大量的代码放入单个try块，实际上这不是好习惯。这种现象之所以常见，原因就在于有些人图省事，不愿花时间分析一大块代码
中哪几行代码会抛出异常、异常的具体类型是什么。把大量的语句装入单个巨大的try块就象是出门旅游时把所有日常用品塞入一个大箱子，虽然东西是带上了，
但要找出来可不容易。</p>
<p>　　一些新手常常把大量的代码放入单个try块，然后再在catch语句中声明Exception，而不是分离各个可能出现异常的段落并分别捕获其异常。这种做法为分析程序抛出异常的原因带来了困难，因为一大段代码中有太多的地方可能抛出Exception.</p>
<p>　　结论五：尽量减小try块的体积。</p>
<p>　　反例之六：输出数据不完整</p>
<p>　　代码：7行-11行。</p>
<p>　　不完整的数据是Java程序的隐形杀手。仔细观察这段代码，考虑一下如果循环的中间抛出了异常，会发生什么事情。循环的执行当然是要被打断的，
其次，catch块会执行？？就这些，再也没有其他动作了。已经输出的数据怎么办？使用这些数据的人或设备将收到一份不完整的（因而也是错误的）数据，却
得不到任何有关这份数据是否完整的提示。对于有些系统来说，数据不完整可能比系统停止运行带来更大的损失。</p>
<p>　　较为理想的处置办法是向输出设备写一些信息，声明数据的不完整性；另一种可能有效的办法是，先缓冲要输出的数据，准备好全部数据之后再一次性输出。</p>
<p>　　结论六：全面考虑可能出现的异常以及这些异常对执行流程的影响。</p>
<p>　　改写后的代码</p>
<p>　　根据上面的讨论，下面给出改写后的代码。也许有人会说它稍微有点？嗦，但是它有了比较完备的异常处理机制。</p>
<p align="center">
</p>
<table bgcolor="#cccccc" cellpadding="0" cellspacing="1" width="80%">
    <tbody>
        <tr>
            <td bgcolor="#f2f2f2">
            <pre>OutputStreamWriter out = ... <br />
            java.sql.Connection conn = ... <br />
            try { <br />
            Statement stat = conn.createStatement(); <br />
            ResultSet rs = stat.executeQuery( <br />
            "select uid, name from user"); <br />
            while (rs.next()) <br />
            { <br />
            out.println("ID：" + rs.getString("uid") + "，姓名: " <br />
            + rs.getString("name")); <br />
            } <br />
            } <br />
            catch(SQLException sqlex) <br />
            { <br />
            out.println("警告：数据不完整"); <br />
            throw new ApplicationException("读取数据时出现SQL错误", sqlex); <br />
            } <br />
            catch(IOException ioex) <br />
            { <br />
            throw new ApplicationException("写入数据时出现IO错误", ioex); <br />
            } <br />
            finally <br />
            { <br />
            if (conn != null) { <br />
            try { <br />
            conn.close(); <br />
            } <br />
            catch(SQLException sqlex2) <br />
            { <br />
            System.err(this.getClass().getName() + ".mymethod - 不能关闭数据库连接: <br />
            " + sqlex2.toString()); <br />
            } <br />
            } <br />
            <br />
            if (out != null) { <br />
            try { <br />
            out.close(); <br />
            } <br />
            catch(IOException ioex2) <br />
            { <br />
            System.err(this.getClass().getName() + ".mymethod - 不能关闭输出文件" <br />
            + ioex2.toString()); <br />
            } <br />
            } <br />
            }</pre>
            </td>
        </tr>
    </tbody>
</table>
<p>　　本文的结论不是放之四海皆准的教条，有时常识和经验才是最好的老师。如果你对自己的做法没有百分之百的信心，务必加上详细、全面的注释。</p>
<p>　　另一方面，不要笑话这些错误，不妨问问你自己是否真地彻底摆脱了这些坏习惯。即使最有经验的程序员偶尔也会误入歧途，原因很简单，因为它们确确
实实带来了&#8220;方便&#8221;。所有这些反例都可以看作Java编程世界的恶魔，它们美丽动人，无孔不入，时刻诱惑着你。也许有人会认为这些都属于鸡皮蒜毛的小事，
不足挂齿，但请记住：勿以恶小而为之，勿以善小而不为。</p>
</span>
<img src ="http://www.blogjava.net/shangaijun/aggbug/159032.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shangaijun/" target="_blank">尚爱军</a> 2007-11-08 10:45 <a href="http://www.blogjava.net/shangaijun/archive/2007/11/08/159032.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何学习Hibernate</title><link>http://www.blogjava.net/shangaijun/archive/2007/11/01/157512.html</link><dc:creator>尚爱军</dc:creator><author>尚爱军</author><pubDate>Thu, 01 Nov 2007 07:54:00 GMT</pubDate><guid>http://www.blogjava.net/shangaijun/archive/2007/11/01/157512.html</guid><wfw:comment>http://www.blogjava.net/shangaijun/comments/157512.html</wfw:comment><comments>http://www.blogjava.net/shangaijun/archive/2007/11/01/157512.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.blogjava.net/shangaijun/comments/commentRss/157512.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shangaijun/services/trackbacks/157512.html</trackback:ping><description><![CDATA[<span style="font-family: Georgia;">
<span class="STYLE2">
<div id="article">
<p><font face="Verdana">Hibernate
入门容易，掌握精通我也不敢自夸。我第一遍看Hibernate文档的时候也觉得很吃力，但不是因为Hibernate难掌握而感到吃力，是因为
Hibernate文档处处都是持久层设计的经验和最佳实践。Hibernate文档准确的来说，绝大部分内容都在讲对象的持久层设计，而不是简单的
Hibernate使用，使用问题查Java
doc就够了。所以学习Hibernate，主要是在学习持久层的设计模式，如果你把Hibernate文档都看完了，还整天只会提那些
Hibernate的配置问题，Hibernate的类调用问题，我觉得这样的人还没有真正的入门，算是白学了。</font></p>
<p><font face="Verdana">我对Hibernate
的那些配置也不是特别纯熟，每次写hbm，都要对照文档一点点的检查；类调用参数也不太记得，写代码也要Java
doc随时备查。但是我在学习Hibernate的时候即集中所有精力来理解Hibernate的运行原理，集中精力来掌握持久层设计应该把握的原则和技
巧，这些才对我是最重用的东西。毫不夸张的说，学习完Hibernate，我对JDBC的编程也提高了一大截，更不要说对于J2EE架构的持久层的框架设
计，基本上是了然于胸了，即使将来换了API，不用Hibernate的，改用JDO，Castor什么的，这些经验一样照用。</font></p>
<p><font face="Verdana">学习Hibernate主要不是在学习Hibernat怎么配置，用工具怎么生成hbm文件，如果你把
重点放在这里，基本上等于白学了Hibernate。Hibernate的精华在于无与伦比的灵巧的对象持久层设计，这些持久层设计经验不会因为你不用
Hibernate而丧失掉，我自己学习Hibernate，已经明显感觉到对持久层设计能力已经长了很多经验值了，这些经验甚至不光可以用在Java
上，用在.net上也是一样。所以Hibernate配置的学习，我只是简单看看，用的时候知道到那里去查就行了，一堆复杂的生成工具我根本就看都不去
看，这样算下来，掌握Hibernate的配置，可以用Hibernate来替代JDBC写程序，不过花上3天时间就足够了。我想3天时间对你来说不算很
奢侈的学习代价吧。</font></p>
<p><font face="Verdana">为什么我这么强调学习Hibernate的对象持久层设计理念呢？那就看你的理想是想一辈子做一个程序
员呢？还是想向更高的方向发展呢？从纯做技术的角度来说，职业发展的最高点是&#8220;系统架构师&#8221;，Bill
Gates不是还叫做微软的首席系统架构师吗？System
Architect职位需要的是你的学习和领悟能力，如果你不能把学习Hibernate得到的设计经验运用到其它地方，那么你是失败的，也没有资格做
System Architect。</font></p>
<p><font face="Verdana">不管JDO也好，Hibernate也好，TopLink也好，CocoBase也好，还是
Castor，还是什么Torque，OJB，软件的使用和配置方法可以各异，但本质上都是ORM，都是对JDBC的对象持久层封装，所以万变不离其宗，
如果你完整的学习和掌握Hibernate花了1个月的时间，那么你再学习OJB的时间不应该超过1个星期，因为你已经把对象持久层设计都了然于胸了，你
需要的只是熟悉一下OJB的API和配置罢了，至于怎么运用OJB进行持久层的开发你早就已经熟悉了。</font></p>
<p><font face="Verdana">所以当你掌握了两种以上的ORM，你应该能够不拘于使用的ORM软件的限制，设计出适合于你的项目的持
久层来，这才是System
Architect的水准。用金庸小说来打个比方来说吧，张无忌学太极剑，只记剑意，不记剑招，这才是真正的高手，而低手就只会去学习剑招，而不去领会剑
招背后蕴含的剑意，所以一辈子都是低手，永远不能真正学会太极剑。所以周颠看到张三丰第二次演示太极剑，招式完全不同就以为是另一套东西，其实本质上都一
样。学习Hibernate也不要舍本逐末的去学各种五花八门的工具，重点掌握它的对象持久层设计理念。</font></p>
</div>
</span>
</span>
<img src ="http://www.blogjava.net/shangaijun/aggbug/157512.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shangaijun/" target="_blank">尚爱军</a> 2007-11-01 15:54 <a href="http://www.blogjava.net/shangaijun/archive/2007/11/01/157512.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Servlet2.3规范 转载</title><link>http://www.blogjava.net/shangaijun/archive/2007/08/18/137865.html</link><dc:creator>尚爱军</dc:creator><author>尚爱军</author><pubDate>Sat, 18 Aug 2007 14:22:00 GMT</pubDate><guid>http://www.blogjava.net/shangaijun/archive/2007/08/18/137865.html</guid><wfw:comment>http://www.blogjava.net/shangaijun/comments/137865.html</wfw:comment><comments>http://www.blogjava.net/shangaijun/archive/2007/08/18/137865.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shangaijun/comments/commentRss/137865.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shangaijun/services/trackbacks/137865.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Servlet2.3规范第一章：servlet2.3规范用到了一下的一些规范：J2EE、JSP1.1、JNDI在14章中讲述了规范中的所有的classes类或接口（改文中不讲述）。对开发者而言以下的有些相关的协议：URI、URL、HTTP/1.0、MIME、HTCPCP/1.0、XML1.1 什么是servlet？servlet是一个基于java技术的web组件，该组件被容器管理，能被编译成字节码...&nbsp;&nbsp;<a href='http://www.blogjava.net/shangaijun/archive/2007/08/18/137865.html'>阅读全文</a><img src ="http://www.blogjava.net/shangaijun/aggbug/137865.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shangaijun/" target="_blank">尚爱军</a> 2007-08-18 22:22 <a href="http://www.blogjava.net/shangaijun/archive/2007/08/18/137865.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java入门与提高 -- 6.java.util篇 转载</title><link>http://www.blogjava.net/shangaijun/archive/2007/08/16/137264.html</link><dc:creator>尚爱军</dc:creator><author>尚爱军</author><pubDate>Thu, 16 Aug 2007 06:49:00 GMT</pubDate><guid>http://www.blogjava.net/shangaijun/archive/2007/08/16/137264.html</guid><wfw:comment>http://www.blogjava.net/shangaijun/comments/137264.html</wfw:comment><comments>http://www.blogjava.net/shangaijun/archive/2007/08/16/137264.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/shangaijun/comments/commentRss/137264.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shangaijun/services/trackbacks/137264.html</trackback:ping><description><![CDATA[<p style="FONT-FAMILY: Georgia">48 java能动态分配数组吗？ <br>　　答：可以。例如int n = 3; Language[] myLanguages = new Language[n]; </p>
<p style="FONT-FAMILY: Georgia">49 我怎么知道数组的长度？ <br>　　答：用length属性。如上例中的 myLanguages.length 就为 3。 </p>
<p style="FONT-FAMILY: Georgia">50 我还想让数组的长度能自动改变，能够增加/删除元素。 <br>　　答：用顺序表--java.util.List接口。 <br>　　你可以选择用ArrayList或是LinkedList，前者是数组实现，后者是链表实现。 <br>　　例如： List list = new ArrayList(); 或是 List list = new LinkedList(); 。 </p>
<p style="FONT-FAMILY: Georgia">51 什么是链表？为什么要有两种实现？ <br>　　答：请补习数据结构。 </p>
<p style="FONT-FAMILY: Georgia">52 我想用队列/栈。 <br>　　答：用java.util.LinkedList。 </p>
<p style="FONT-FAMILY: Georgia">53 我希望不要有重复的元素。 <br>　　答：用集合--java.util.Set接口。例如：Set set = new HashSet()。 </p>
<p style="FONT-FAMILY: Georgia">54 我想遍历集合/Map。 <br>　　答：用java.util.Iterator。参见API。 </p>
<p style="FONT-FAMILY: Georgia">55 我还要能够排序。 <br>　　答：用java.util.TreeSet。例如：Set set = new TreeSet()。放进去的元素会自动排序。 <br>　　你需要为元素实现Comparable接口，还可能需要提供equals()方法，compareTo()方法，hashCode()方法。 </p>
<p style="FONT-FAMILY: Georgia">56 但是我想给数组排序。 <br>　　答：java.util.Arrays类包含了sort等实用方法。 </p>
<p style="FONT-FAMILY: Georgia">57 我想按不同方法排序。 <br>　　答：为每种方法定义一个实现了接口Comparator的类并和Arrays综合运用。 </p>
<p style="FONT-FAMILY: Georgia">58 Map有什么用？ <br>　　答：存储key-value的关键字-值对，你可以通过关键字来快速存取相应的值。 </p>
<p style="FONT-FAMILY: Georgia">59 set方法没问题，但是get方法返回的是Object。 <br>　　答：强制类型转换成你需要的类型。参见45。 </p>
<p style="FONT-FAMILY: Georgia">60 我要获得一个随机数。 <br>　　答：使用java.util.Random类。 </p>
<p style="FONT-FAMILY: Georgia">61 我比较两个String总是false，但是它们明明都是"abc" ！ <br>　　答：比较String一定要使用equals或equalsIgnoreCase方法，不要使用 == ！ <br>　　==比较的是两个引用（变量）是否指向了同一个对象，而不是比较其内容。<br></p>
<img src ="http://www.blogjava.net/shangaijun/aggbug/137264.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shangaijun/" target="_blank">尚爱军</a> 2007-08-16 14:49 <a href="http://www.blogjava.net/shangaijun/archive/2007/08/16/137264.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java入门与加深 -- 5.面向对象篇 转载</title><link>http://www.blogjava.net/shangaijun/archive/2007/08/16/137263.html</link><dc:creator>尚爱军</dc:creator><author>尚爱军</author><pubDate>Thu, 16 Aug 2007 06:48:00 GMT</pubDate><guid>http://www.blogjava.net/shangaijun/archive/2007/08/16/137263.html</guid><wfw:comment>http://www.blogjava.net/shangaijun/comments/137263.html</wfw:comment><comments>http://www.blogjava.net/shangaijun/archive/2007/08/16/137263.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/shangaijun/comments/commentRss/137263.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shangaijun/services/trackbacks/137263.html</trackback:ping><description><![CDATA[<span style="FONT-FAMILY: Georgia">java入门与加深 系列 相关文章<br></span><a href="http://www.ad0.cn/netfetch/article.asp?id=105" target=_blank><span style="FONT-FAMILY: Georgia">(转) java入门与加深 -- 1.基础篇 </span></a><br><a href="http://www.ad0.cn/netfetch/article.asp?id=106" target=_blank><span style="FONT-FAMILY: Georgia">(转) java入门与加深 -- 2.命令篇&nbsp;&nbsp;</span></a><br><a href="http://www.ad0.cn/netfetch/article.asp?id=107" target=_blank><span style="FONT-FAMILY: Georgia">(转) java入门与加深 -- 3.I/O篇&nbsp;&nbsp;</span></a><br><a href="http://www.ad0.cn/netfetch/article.asp?id=108" target=_blank><span style="FONT-FAMILY: Georgia">(转) java入门与加深 -- 4.关键字篇 </span></a><br><a href="http://www.ad0.cn/netfetch/article.asp?id=109" target=_blank><span style="FONT-FAMILY: Georgia">(转) java入门与加深 -- 5.面向对象篇 </span></a><br><a href="http://www.ad0.cn/netfetch/article.asp?id=110" target=_blank><span style="FONT-FAMILY: Georgia">(转) java入门与加深 -- 6.java.util篇 </span></a><br><br><span style="FONT-FAMILY: Georgia">34 extends和implements有什么不同？ <br>　　答：extends用于（单）继承一个类（class），而implements用于实现一个接口（interface）。 <br>　　interface的引入是为了部分地提供多继承的功能。 <br>　　在interface中只需声明方法头，而将方法体留给实现的class来做。 <br>　　这些实现的class的实例完全可以当作interface的实例来对待。 <br>　　有趣的是在interface之间也可以声明为extends（单继承）的关系。 <br><br>35 java怎么实现多继承？ <br>　　答：java不支持显式的多继承。 <br>　　因为在显式多继承的语言例如c++中，会出现子类被迫声明祖先虚基类构造函数的问题， <br><br>　　而这是违反面向对象的封装性原则的。 <br>　　java提供了interface和implements关键字来部分地实现多继承。参见34。 <br><br>36 abstract是什么？ <br>　　答：被声明为abstract的方法无需给出方法体，留给子类来实现。 <br>　　而如果一个类中有abstract方法，那么这个类也必须声明为abstract。 <br>　　被声明为abstract的类无法实例化，尽管它可以定义构造方法供子类使用。 <br><br>37 public,protected,private有什么不同？ <br>　　答：这些关键字用于声明类和成员的可见性。 <br>　　public成员可以被任何类访问， <br>　　protected成员限于自己和子类访问， <br>　　private成员限于自己访问。 <br>　　Java还提供了第四种的默认可见性，当没有任何public,protected,private修饰时，成员是包内可见<br>　　类可以用public或默认来修饰。 <br><br>38 Override和Overload有什么不同？ <br>　　答：Override是指父类和子类之间方法的继承关系，这些方法有着相同的名称和参数类型。 <br>　　Overload是指同一个类中不同方法（可以在子类也可以在父类中定义）间的关系，这些方法有着相同的名称和不同的参数类型。 <br><br>39 我继承了一个方法，但现在我想调用在父类中定义的方法。 <br>　　答：用super.xxx()可以在子类中调用父类方法。 <br><br>40 我想在子类的构造方法中调用父类的构造方法，该怎么办？ <br>　　答：在子类构造方法的第一行调用super(...)即可。 <br><br>41 我在同一个类中定义了好几个构造方法并且想在一个构造方法中调用另一个。 <br>　　答：在构造方法第一行调用this(...)。 <br><br>42 我没有定义构造方法会怎么样？ <br>　　答：自动获得一个无参数的构造方法。 <br><br>43 我调用无参数的构造方法失败了。 <br>　　答：如果你至少定义了一个构造方法，就不再有自动提供的无参数的构造方法了。 <br>　　你需要显式定义一个无参数的构造方法。 <br><br>44 我该怎么定义类似于C++中的析构方法（destructor）？ <br>　　答：提供一个void finalize()方法。在Garbarge Collector回收该对象时会调用该方法。 <br>　　注意实际上你很难判断一个对象会在什么时候被回收。作者从未感到需要提供该方法。 <br><br>45 我想将一个父类对象转换成一个子类对象该怎么做？ <br>　　答：强制类型转换。如 <br>　　public void meth(A a) <br>　　{ <br>　　B b = (B)a; <br>　　} <br>　　如果a实际上并不是B的实例，会抛出ClassCastException。所以请确保a确实是B的实例 <br>　　。 <br><br>46 其实我不确定a是不是B的实例，能不能分情况处理？ <br>　　答：可以使用instanceof操作符。例如 <br>　　if( a instanceof B ) <br>　　{ <br>　　B b = (B)a; <br>　　} <br>　　else <br>　　{ <br>　　... <br><br><br>　　} <br><br>47 我在方法里修改了一个对象的值，但是退出方法后我发现这个对象的值没变！ <br>　　答：很可能你把传入参数重赋了一个新对象，例如下列代码就会造成这种错误： <br>　　public void fun1(A a) //a是局部参数，指向了一个外在对象。 <br>　　{ <br>　　a = new A(); //a指向了一个新对象，和外在对象脱钩了。如果你要让a作为传 <br>　　出变 <br>　　量，不要写这一句。 <br>　　a.setAttr(attr);//修改了新对象的值，外在对象没有被修改。 <br>　　} <br>　　基本类型也会出现这种情况。例如： <br>　　public void fun2(int a) <br>　　{ <br>　　a = 10;//只作用于本方法，外面的变量不会变化。 <br>　　} <br></span>
<img src ="http://www.blogjava.net/shangaijun/aggbug/137263.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shangaijun/" target="_blank">尚爱军</a> 2007-08-16 14:48 <a href="http://www.blogjava.net/shangaijun/archive/2007/08/16/137263.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java入门与加深 -- 4.关键字篇 转载</title><link>http://www.blogjava.net/shangaijun/archive/2007/08/16/137261.html</link><dc:creator>尚爱军</dc:creator><author>尚爱军</author><pubDate>Thu, 16 Aug 2007 06:47:00 GMT</pubDate><guid>http://www.blogjava.net/shangaijun/archive/2007/08/16/137261.html</guid><wfw:comment>http://www.blogjava.net/shangaijun/comments/137261.html</wfw:comment><comments>http://www.blogjava.net/shangaijun/archive/2007/08/16/137261.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shangaijun/comments/commentRss/137261.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shangaijun/services/trackbacks/137261.html</trackback:ping><description><![CDATA[<p>25 java里面怎么定义宏？ <br>　　答：java不支持宏，因为宏代换不能保证类型安全。 <br>　　如果你需要定义常量，可以将它定义为某个类的static final成员。参见26和30。 </p>
<p>26 java里面没法用const。 <br>　　答：你可以用final关键字。例如 final int m = 9。被声明为final的变量不能被再次赋值?final也可以用于声明方法或类，被声明为final的方法或类不能被继承 。 <br>　　注意const是java的保留字以备扩充。 </p>
<p>27 java里面也不能用goto。 <br>　　答：甚至在面向过程的语言中你也可以完全不用goto。请检查你的程序流程是否合理。 <br>　　如果你需要从多层循环中迅速跳出，java增强了（和C++相比）break和continue的功能，支持label。 </p>
<p>　　例如： <br>　　outer : <br>　　while( ... ) <br>　　{ <br>　　inner : <br>　　for( ... ) <br>　　{ <br>　　... break inner; ... <br>　　... continue outer; ... <br>　　} <br>　　} <br>　　和const一样，goto也是java的保留字以备扩充。 </p>
<p>28 java里面能不能重载操作符？ <br>　　答：不能。String的+号是唯一一个内置的重载操作符。你可以通过定义接口和方法来实现类 <br>　　似功能。 </p>
<p>29 我new了一个对象，但是没法delete掉它。 <br>　　答：java有自动内存回收机制，即所谓Garbarge Collector。你再也不用担心指针错误</p>
<p>30 我想知道为什么main方法必须被声明为public static？ <br>　　答：声明为public是为了这个方法可以被外部调用，详情见面向对象篇37。 <br>　　static是为了将某个成员变量/方法关联到类（class）而非实例（instance）。 <br>　　你不需要创建一个对象就可以直接使用这个类的static成员， <br>　　在A类中调用B类的static成员可以使用B.staticMember的写法。 <br>　　注意一个类的static成员变量是唯一的，被所有该类对象所共享的。 </p>
<p>31 throw和throws有什么不同？ <br>　　答：throws用于声明一个方法会抛出哪些异常。而throw是在方法体中实际执行抛出异常 <br>　　的动作。 <br>　　如果你在方法中throw一个异常，却没有在方法声明中声明之，编译器会报错。 <br>　　注意Error和RuntimeException的子类是例外，无需特别声明。 </p>
<p>32 什么是异常？ <br>　　答：异常最早在Ada语言中引入，用于在程序中动态处理错误并恢复。 <br>　　你可以在方法中拦截底层异常并处理之，也可以抛给更高层的模块去处理。 <br>　　你也可以抛出自己的异常指示发生了某些不正常情况。常见的拦截处理代码如下： <br>　　try <br>　　{ <br>　　...... //以下是可能发生异常的代码 <br>　　...... //异常被抛出，执行流程中断并转向拦截代码。 <br>　　...... <br>　　} </p>
<p><br>　　catch(Exception1 e) //如果Exception1是Exception2的子类并要做特别处理，应排在 <br>　　前面 <br>　　{ <br>　　//发生Exception1时被该段拦截 <br>　　} <br>　　catch(Exception2 e) <br>　　{ <br>　　//发生Exception2时被该段拦截 <br>　　} <br>　　finally //这是可选的 <br>　　{ <br>　　//无论异常是否发生，均执行此段代码 <br>　　} </p>
<p style="FONT-FAMILY: Georgia">33 final和finally有什么不同？ <br>　　答：final请见26。finally用于异常机制，参见32。 <br></p>
<img src ="http://www.blogjava.net/shangaijun/aggbug/137261.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shangaijun/" target="_blank">尚爱军</a> 2007-08-16 14:47 <a href="http://www.blogjava.net/shangaijun/archive/2007/08/16/137261.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> java入门与加深 -- 3.I/O篇 转载</title><link>http://www.blogjava.net/shangaijun/archive/2007/08/16/137260.html</link><dc:creator>尚爱军</dc:creator><author>尚爱军</author><pubDate>Thu, 16 Aug 2007 06:46:00 GMT</pubDate><guid>http://www.blogjava.net/shangaijun/archive/2007/08/16/137260.html</guid><wfw:comment>http://www.blogjava.net/shangaijun/comments/137260.html</wfw:comment><comments>http://www.blogjava.net/shangaijun/archive/2007/08/16/137260.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/shangaijun/comments/commentRss/137260.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shangaijun/services/trackbacks/137260.html</trackback:ping><description><![CDATA[<p style="FONT-FAMILY: Georgia">18 我怎么给java程序加启动参数，就像dir /p/w那样？ <br>　　答：还记得public static void main(String[] args)吗？这里的args就是你的启动参数。 <br>　　在运行时你输入java package1.class1 -arg1 -arg2，args中就会有两个String，一个是arg1，另一个是arg2。 </p>
<p style="FONT-FAMILY: Georgia">19 我怎么从键盘输入一个int/double/字符串？ <br>　　答：java的I/O操作比C++要复杂一点。如果要从键盘输入，样例代码如下： <br>　　BufferedReader cin = new BufferedReader( new InputStreamReader( System.in ) ) ; <br>　　String s = cin.readLine(); <br>　　这样你就获得了一个字符串，如果你需要数字的话再加上： <br>　　int n = Integer.parseInt( s ); 或者 double d = Double.parseDouble( s ); </p>
<p style="FONT-FAMILY: Georgia">20 我怎么输出一个int/double/字符串？ <br>　　答：在程序开始写： <br>　　PrintWriter cout = new PrintWriter( System.out ); 需要时写：cout.print(n); 或者 out.println("hello")等等。 </p>
<p style="FONT-FAMILY: Georgia">21 我发现有些书上直接用System.in和System.out输入输出，比你要简单得多。 <br>　　答：java使用unicode，是双字节。而System.in和System.out是单字节的stream。 <br>　　如果你要输入输出双字节文字比如中文，请使用作者的做法。 </p>
<p style="FONT-FAMILY: Georgia">22 我怎么从文件输入一个int/double/字符串？ <br>　　答：类似于从键盘输入，只不过换成 <br>　　BufferedReader fin = new BufferedReader( new FileReader(" myFileName " ) ); <br>　　PrintWriter fout = new PrintWriter( new FileWriter(" myFileName " ) ); <br>　　另外如果你还没下载API，请开始下载并阅读java.io包中的内容。 </p>
<p style="FONT-FAMILY: Georgia">23 我想读写文件的指定位置，该怎么办？ <br>　　答：你肯定没有认真看API。java.io.RandomAccessFile可以满足你的需要。 </p>
<p style="FONT-FAMILY: Georgia">24 怎么判断要读的文件已经到了尽头？ <br>　　答：你肯定没有认真看API。在Reaer的read方法中明确说明返回-1表示流的结尾。 </p>
<img src ="http://www.blogjava.net/shangaijun/aggbug/137260.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shangaijun/" target="_blank">尚爱军</a> 2007-08-16 14:46 <a href="http://www.blogjava.net/shangaijun/archive/2007/08/16/137260.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java入门与加深 -- 2.命令篇 转载</title><link>http://www.blogjava.net/shangaijun/archive/2007/08/16/137257.html</link><dc:creator>尚爱军</dc:creator><author>尚爱军</author><pubDate>Thu, 16 Aug 2007 06:45:00 GMT</pubDate><guid>http://www.blogjava.net/shangaijun/archive/2007/08/16/137257.html</guid><wfw:comment>http://www.blogjava.net/shangaijun/comments/137257.html</wfw:comment><comments>http://www.blogjava.net/shangaijun/archive/2007/08/16/137257.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shangaijun/comments/commentRss/137257.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shangaijun/services/trackbacks/137257.html</trackback:ping><description><![CDATA[<p style="FONT-FAMILY: Georgia">7 我写了第一个Java程序，应该如何编译/运行？ <br>　　答：首先请将程序保存为xxx.java文件， <br>　　然后在dos窗口下使用javac xxx.java命令，你会发现该目录下多了一个xxx.class文件，再使用java xxx命令，你的java程序就开始运行了。 </p>
<p style="FONT-FAMILY: Georgia">8 我照你说的做了，但是出现什么"&#180;javac&#180; 不是内部或外部命令，也不是可运行的程序或批处理文件。"。 <br>　　答：你遇到了path问题。操作系统在一定的范围(path)内搜索javac.exe，但是没能找到。 <br>　　请编辑你的操作系统环境变量，新增一个JAVA_HOME变量，设为你JDK的安装目录， <br>　　再编辑Path变量，加上一项 %JAVA_HOME%\bin。 <br>　　然后关掉并新开一个dos窗口，你就可以使用javac和java命令了。 </p>
<p style="FONT-FAMILY: Georgia">9 环境变量怎么设置？ <br>　　答：请向身边会设的人咨询。 java初学者必读-经验总结 这篇文章中比较详细的讲到 jdk开发中系统环境变量设置 以及相关 服务器配置等开发环境配置。</p>
<p style="FONT-FAMILY: Georgia">10 javac xxx.java顺利通过了，但是java xxx的时候显示什么"NoClassDefFoundError"<br>　　答：你遇到了classpath问题。java命令在一定的范围(classpath)内搜索你要用的class文件，但是未能找到。 <br>　　首先请确认你没有错敲成java xxx.class， <br>　　其次，检查你的CLASSPATH环境变量，如果你设置了该变量又没有包含.（代表当前目录）你就会遇到这个问题。请在你的CLASSPATH环境变量中加入一项. 。另 <br>　　外参见15。 </p>
<p style="FONT-FAMILY: Georgia">11 我在java xxx的时候显示"Exception in thread "main" java.lang.NoSuchMethodError: main"。 <br>　　答：首先，在你的程序中每个java文件有且只能有一个public类， <br>　　这个类的类名必须和文件名的大小写完全一样。 <br>　　其次，在你要运行的类中有且只能有一个public static void main(String[] args)方法，这个方法就是你的主程序。 </p>
<p style="FONT-FAMILY: Georgia">12 package是什么意思？怎么用？ <br>　　答：为了唯一标识每个类并分组，java使用了package的概念。 <br>　　每个类都有一个全名，例如String的全名是java.lang.String，其中java.lang是包名，String是短名。 <br>　　这样，如果你也定义了String，你可以把它放在mypackage中， <br>　　通过使用全名mypackage.String和java.lang.String来区分这两个类。 <br>　　同时，将逻辑上相关的类放在同一个包中，可以使程序结构更为清楚。 </p>
<p style="FONT-FAMILY: Georgia">　　你要做的就是在java文件开头加一行"package mypackage;"。 <br>　　注意包没有嵌套或包含关系，A包和A.B包对java命令来说是并列的两个包</p>
<p style="FONT-FAMILY: Georgia">13 我没有声明任何package会怎么样？ <br>　　答：你的类被认为放在默认包中。这时全名和短名是一致的。 </p>
<p style="FONT-FAMILY: Georgia">14 在一个类中怎么使用其他类？ <br>　　答：如果你使用java.lang包中的类，不用做任何事。 <br>　　如果你使用其他包中的类，使用import package1.class1; 或 import package2.*; <br>　　这里.*表示引入这个包中的所有类。然后在程序中你可以使用其他类的短名。 <br>　　如果短名有冲突，使用全名来区分。 </p>
<p style="FONT-FAMILY: Georgia">15 我用了package的时候显示"NoClassDefFoundError"，但是我把所有package去掉的时候能正常运行。 <br>　　答：将你的java文件按包名存放。 <br>　　比如你的工作目录是/work，你的类是package1.class1，那么将它存放为/work/package1/class1.java。<br>　　如果没有声明包，那么直接放在/work下。 <br>　　在/work下执行javac package1/class1.java，再执行java package1.class1，你会发现 <br>　　一切正常。<br>　　另外，你可以考虑开始使用IDE。 </p>
<p style="FONT-FAMILY: Georgia">16 我想把java编译成exe文件，该怎么做？ <br>　　答：JDK只能将java源文件编译为class文件。 <br>　　class文件是一种跨平台的字节码，必须依赖平台相关的JRE来运行。Java以此来实现跨平台，有些开发工具可以将java文件编译为exe文件。作者反对这种做法，因为这样就取消了跨平台性。 <br>　　如果你确信你的软件只在Windows平台上运行，你可以考虑使用C++/C#来编程。 </p>
<p style="FONT-FAMILY: Georgia">17 我在编译的时候遇到什么"deprecated API"，是什么意思？ <br>　　答：所谓deprecated是指已经?时，但是为了向前兼容起见仍然保留的方法?这些方法可能会在以后取消支持。你应当改用较新的方法。 <br>　　一般在API里面会说明你应当用什么方法来代替之。 <br></p>
<img src ="http://www.blogjava.net/shangaijun/aggbug/137257.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shangaijun/" target="_blank">尚爱军</a> 2007-08-16 14:45 <a href="http://www.blogjava.net/shangaijun/archive/2007/08/16/137257.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java入门与加深 -- 1.基础篇  转载</title><link>http://www.blogjava.net/shangaijun/archive/2007/08/16/137256.html</link><dc:creator>尚爱军</dc:creator><author>尚爱军</author><pubDate>Thu, 16 Aug 2007 06:44:00 GMT</pubDate><guid>http://www.blogjava.net/shangaijun/archive/2007/08/16/137256.html</guid><wfw:comment>http://www.blogjava.net/shangaijun/comments/137256.html</wfw:comment><comments>http://www.blogjava.net/shangaijun/archive/2007/08/16/137256.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shangaijun/comments/commentRss/137256.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shangaijun/services/trackbacks/137256.html</trackback:ping><description><![CDATA[<p style="FONT-FAMILY: Georgia">1 什么是Java、Java2、JDK？JDK后面的1.3、1.4.2版本号又是怎么回事？ <br>　　答：Java是一种通用的，并发的，强类型的，面向对象的编程语言（摘自Java规范第二版) JDK是Sun公司分发的免费Java开发工具，正式名称为J2SDK(Java2 Softw are Develop Kit)。 </p>
<p style="FONT-FAMILY: Georgia">2 什么是JRE/J2RE？ <br>　　答：J2RE是Java2 Runtime Environment，&nbsp;&nbsp; 即Java运行环境，有时简称JRE。 <br>如果你只需要运行Java程序或Applet， 下载并安装它即可。如果你要自行开发Java软件，请下载JDK。在JDK中附带有J2RE。<br>　　注意由于Microsoft对Java的支持不完全，请不要使用IE自带的虚拟机来运行Applet，务必安装一个J2RE或JDK。 </p>
<p style="FONT-FAMILY: Georgia">3 学习Java用什么工具比较好？ <br>　答：作者建议首先使用JDK+文本编辑器，这有助你理解下列几个基础概念：path，classpath，package并熟悉基本命令：javac和java。并且下载和你的JDK版本一致的API帮助。 <br>　　如果你不确定类或函数的用法，请先查阅API而不是发贴求助。 <br>　　当你熟悉Java之后，你可以考虑换一个IDE。很多人推荐Jcreator，实际上Jcreator的功能还 是很弱的。 <br>　　作者推荐eclipse，下载网址<a href="http://www.eclipse.org/">http://www.eclipse.org</a> ;。因eclispe是免费的. </p>
<p style="FONT-FAMILY: Georgia">4 学习Java有哪些好的参考书？ <br>　　答：作者首先推荐Thinking in Java，中文名《Java编程思想》，有中文版。该书第一章介绍了很多面向对象的编程思想，作为新手应当认真阅读。除此以外，O&#180;relly出版社和Wrox出版社的书也不错。作者本人不喜欢大陆作者的书。也许你觉得英文太难，但是网上大多数资料都是英文的。另外，你需要经常查阅API，而那也是英文的。 </p>
<p style="FONT-FAMILY: Georgia">5 Java和C++哪个更好？ <br>　　答：这个问题是一个很不恰当的问题。你应该问：Java和C++哪个更适用于我的项目？ 如果你不需要跨平台，不需要分布式，要强调程序的运行速度，C++更为适用。反之?你应当考虑Java。 </p>
<p style="FONT-FAMILY: Georgia">6 什么是J2SE/J2EE/J2ME？&nbsp;&nbsp; <br>　　答：J2SE就是一般的Java。 <br>　　J2ME是针对嵌入式设备的，比如Java手机，它有自己的SDK。而J2EE使用J2SE的SDK。 <br>　　J2EE规范更多的是对J2EE服务器的要求和开发人员的约束。详情见后继《J2EE FAQ》。<br></p>
<img src ="http://www.blogjava.net/shangaijun/aggbug/137256.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shangaijun/" target="_blank">尚爱军</a> 2007-08-16 14:44 <a href="http://www.blogjava.net/shangaijun/archive/2007/08/16/137256.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>初学者如何开发出一个高质量的J2EE系统</title><link>http://www.blogjava.net/shangaijun/archive/2007/08/12/136160.html</link><dc:creator>尚爱军</dc:creator><author>尚爱军</author><pubDate>Sun, 12 Aug 2007 06:37:00 GMT</pubDate><guid>http://www.blogjava.net/shangaijun/archive/2007/08/12/136160.html</guid><wfw:comment>http://www.blogjava.net/shangaijun/comments/136160.html</wfw:comment><comments>http://www.blogjava.net/shangaijun/archive/2007/08/12/136160.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/shangaijun/comments/commentRss/136160.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shangaijun/services/trackbacks/136160.html</trackback:ping><description><![CDATA[<span style="FONT-FAMILY: Georgia">J2EE学习者越来越多，J2EE本身技术不断在发展，涌现出各种概念，本文章试图从一种容易理解的角度对这些概念向初学者进行解释，以便掌握学习J2EE学习方向。<br><br>　　首先我们需要知道Java和J2EE是两个不同概念，Java不只是指一种语言，已经代表与微软不同的另外一个巨大阵营，所以Java有时是指一种软件系统的流派，当然目前主要是.NET和Java两大主流体系。<br><br>　　J2EE可以说指Java在数据库信息系统上实现，数据库信息系统从早期的dBase、到Delphi/VB等C/S结构，发展到B/S（Browser浏览器/Server服务器）结构，而J2EE主要是指B/S结构的实现。<br><br>　　J2EE又是一种框架和标准，框架类似API、库的概念，但是要超出它们。如果需要详细了解框架，可先从设计模式开始学习。<br><br>　　J2EE是一个虚的大的概念，J2EE标准主要有三种子技术标准：WEB技术、EJB技术和JMS，谈到J2EE应该说最终要落实到这三个子概念上。<br><br>　　这三种技术的每个技术在应用时都涉及两个部分：容器部分和应用部分，Web容器也是指Jsp/Servlet容器，你如果要开发一个Web应用，无论是编译或运行，都必须要有Jsp/Servlet库或API支持（除了JDK/J2SE以外）。<br><br>　　Web技术中除了Jsp/Servlet技术外，还需要JavaBeans或Java Class实现一些功能或者包装携带数据，所以Web技术最初裸体简称为Jsp/Servlet+JavaBeans系统。<br><br>　　谈到JavaBeans技术，就涉及到组件构件技术（component），这是Java的核心基础部分，很多软件设计概念（设计模式）都是通过JavaBeans实现的。<br><br>　　JavaBeans不属于J2EE概念范畴中，如果一个JavaBeans对象被Web技术（也就是Jsp/Servlet）调用，那么JavaBeans就运行在J2EE的Web容器中；如果它被EJB调用，它就运行在EJB容器中。<br><br>　　EJB（企业JavaBeans）是普通JavaBeans的一种提升和规范，因为企业信息系统开发中需要一个可伸缩的性能和事务、安全机制，这样能保证企业系统平滑发展，而不是发展到一种规模重新更换一套软件系统。<br><br>　　至此，JavaBeans组件发展到EJB后，并不是说以前的那种JavaBeans形式就消失了，这就自然形成了两种JavaBeans技术：EJB和POJO，POJO完全不同于EJB概念，指的是普通JavaBeans，而且这个JavaBeans不依附某种框架，或者干脆可以说：这个JavaBeans是你为这个应用程序单独开发创建的。<br><br>　　J2EE应用系统开发工具有很多：如JBuilder、Eclipse等，这些IDE首先是Java开发工具，也就是说，它们首要基本功能是可以开发出JavaBeans或Java class，但是如果要开发出J2EE系统，就要落实到要么是Web技术或EJB技术，那么就有可能要一些专门模块功能(如eclipse需要lomboz插件)，最重要的是，因为J2EE系统区分为容器和应用两个部分，所以，在任何开发工具中开发J2EE都需要指定J2EE容器。<br><br>　　J2EE容器分为WEB容器和EJB容器，Tomcat/Resin是Web容器；JBoss是EJB容器+Web容器等，其中Web容器直接使用Tomcat实现的。所以你开发的Web应用程序可以在上面两种容器运行，而你开发的Web+EJB应用则只可以在JBoss服务器上运行，商业产品Websphere/Weblogic等和JBoss属于同一种性质。<br><br>　　J2EE容器也称为J2EE服务器，大部分时它们概念是一致的。<br><br>　　如果你的J2EE应用系统的数据库连接是通过JNDI获得，也就是说是从容器中获得，那么你的J2EE应用系统基本与数据库无关，如果你在你的J2EE应用系统耦合了数据库JDBC驱动的配置，那么你的J2EE应用系统就有数据库概念色彩，作为一个成熟需要推广的J2EE应用系统，不推荐和具体数据库耦合，当然这其中如何保证J2EE应用系统运行性能又是体现你的设计水平了。<br><br>　　衡量J2EE应用系统设计开发水平高低的标准就是：解耦性；你的应用系统各个功能是否能够彻底脱离？是否不相互依赖，也只有这样，才能体现可维护性、可拓展性的软件设计目标。<br><br>　　为了达到这个目的，诞生各种框架概念，J2EE框架标准将一个系统划分为WEB和EJB主要部分，当然我们有时不是以这个具体技术区分，而是从设计上抽象为表现层、服务层和持久层，这三个层次从一个高度将J2EE分离开来，实现解耦目的。<br><br>　　因此，我们实际编程中，也要将自己的功能向这三个层次上靠，做到大方向清楚，泾渭分明，但是没有技术上约束限制要做到这点是很不容易的，因此我们还是必须借助J2EE具体技术来实现，这时，你可以使用EJB规范实现服务层和持久层，Web技术实现表现层；<br><br>　　EJB为什么能将服务层从Jsp/Servlet手中分离出来，因为它对JavaBeans编码有强制的约束，现在有一种对JavaBeans弱约束，使用Ioc模式实现的（当然EJB 3.0也采取这种方式），在Ioc模式诞生前，一般都是通过工厂模式来对JavaBeans约束，形成一个服务层，这也是是Jive这样开源论坛设计原理之一。<br><br>　　由此，将服务层从表现层中分离出来目前有两种可选架构选择：管理普通JavaBeans（POJO）框架(如Spring、JdonFramework)以及管理EJB的EJB框架，因为EJB不只是框架，还是标准，而标准可以扩展发展，所以，这两种区别将来是可能模糊，被纳入同一个标准了。　但是，个人认为：标准制定是为某个目的服务的，总要牺牲一些换取另外一些，所以，这两种架构会长时间并存。<br><br>　　这两种架构分歧也曾经诞生一个新名词：完全POJO的系统也称为轻量级系统(lightweight)，其实这个名词本身就没有一个严格定义，更多是一个吸引人的招牌，轻量是指容易学习容易使用吗？按照这个定义，其实轻量Spring等系统并不容易学习；而且EJB 3.0（依然叫EJB）以后的系统是否可称为轻量级了呢？<br><br>　　前面谈了服务层框架，使用服务层框架可以将JavaBeans从Jsp/Servlet中分离出来，而使用表现层框架则可以将Jsp中剩余的JavaBeans完全分离，这部分JavaBeans主要负责显示相关，一般是通过标签库（taglib）实现，不同框架有不同自己的标签库，Struts是应用比较广泛的一种表现层框架。<br><br>　　这样，表现层和服务层的分离是通过两种框架达到目的，剩余的就是持久层框架了，通过持久层的框架将数据库存储从服务层中分离出来是其目的，持久层框架有两种方向：直接自己编写JDBC等SQL语句（如iBatis）；使用O/R Mapping技术实现的Hibernate和JDO技术；当然还有EJB中的实体Bean技术。<br><br>　　持久层框架目前呈现百花齐放，各有优缺点的现状，所以正如表现层框架一样，目前没有一个框架被指定为标准框架，当然，表现层框架现在又出来了一个JSF，它代表的页面组件概念是一个新的发展方向，但是复杂的实现让人有些忘而却步。<br><br>　　在所有这些J2EE技术中，虽然SUN公司发挥了很大的作用，不过总体来说：网络上有这样一个评价：SUN的理论天下无敌；SUN的产品用起来撞墙；对于初学者，特别是那些试图通过或已经通过SUN认证的初学者，赶快摆脱SUN的阴影，立即开溜，使用开源领域的产品来实现自己的应用系统。<br><br>　　最后，你的J2EE应用系统如果采取上面提到的表现层、服务层和持久层的框架实现，基本你也可以在无需深刻掌握设计模式的情况下开发出一个高质量的应用系统了。<br><br>　　还要注意的是: 开发出一个高质量的J2EE系统还需要正确的业务需求理解，那么域建模提供了一种比较切实可行的正确理解业务需求的方法，相关详细知识可从UML角度结合理解。<br><br>　　当然，如果你想设计自己的行业框架，那么第一步从设计模式开始吧，因为设计模式提供你一个实现JavaBeans或类之间解耦参考实现方法，当你学会了系统基本单元JavaBean或类之间解耦时，那么系统模块之间的解耦你就可能掌握，进而你就可以实现行业框架的提炼了，这又是另外一个发展方向了。<br><br>　　以上理念可以总结为一句话：<br>J2EE开发三件宝: Domain Model（域建模）、patterns（模式）和framework（框架）。<br><br>　　推荐一套高质量的J2EE开源系统： JPestore <br>　　<br>　　如果初学者没有理解，欢迎继续讨论，大胆提出你心中的疑问</span>
<img src ="http://www.blogjava.net/shangaijun/aggbug/136160.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shangaijun/" target="_blank">尚爱军</a> 2007-08-12 14:37 <a href="http://www.blogjava.net/shangaijun/archive/2007/08/12/136160.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>