﻿<?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-java世界</title><link>http://www.blogjava.net/java2java/</link><description>世界Java</description><language>zh-cn</language><lastBuildDate>Thu, 16 Apr 2026 23:16:20 GMT</lastBuildDate><pubDate>Thu, 16 Apr 2026 23:16:20 GMT</pubDate><ttl>60</ttl><item><title>JAVA运行时的产间错误</title><link>http://www.blogjava.net/java2java/archive/2008/03/01/183079.html</link><dc:creator>java2java</dc:creator><author>java2java</author><pubDate>Sat, 01 Mar 2008 01:55:00 GMT</pubDate><guid>http://www.blogjava.net/java2java/archive/2008/03/01/183079.html</guid><wfw:comment>http://www.blogjava.net/java2java/comments/183079.html</wfw:comment><comments>http://www.blogjava.net/java2java/archive/2008/03/01/183079.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/java2java/comments/commentRss/183079.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/java2java/services/trackbacks/183079.html</trackback:ping><description><![CDATA[<pre>1.错误提示内容：Can&#8216;t find class HelloworldApp
<p>　　解释：（当键入<u><strong>java</strong></u> HelloWorldApp时发生该错误。）</p>
<p>　　系统找不到名为HelloWorldApp的类文件。一般地，该错误意味着类名拼写和源文件名不一样，系统创建filename.class文件时使用的是类定义的名字，并且区分大小写。</p>
<p>　　例如：</p>
<p>　　class HelloWorldapp（&#8230;）</p>
<p>　　经<u><strong>编译</strong></u>后将创建HelloWorldapp.class类。执行时，也要使用这个名字。发生这个错误时，可以使用文件查看命令Is或dir看看当前目录下是否存在相应的文件，并检查文件名的大小写。</p>
<p>　　2.错误提示内容：In class HelloWorldApp：main must be public and static</p>
<p>　　解释：如果main（）方法的左侧缺少static或public，会发生这个错误。前面已经解释过对main（）方法前面的修饰符有特殊的要求。</p>
<p>　　3.文件中含有的类个数错误</p>
<p>　　解释：按照Java规则，在一个源文件中最多只能定义一个公有类，否则会发生运行时错误。如果一个应用系统中有多个公有类，则要把它们分别放在各自不同的文件中。文件中非公有类的个数不限。</p>
<p>　　4.层次错误</p>
<p>　　解释：一个。java源文件可以含有三个&#8220;顶层&#8221;元素，这三个元素是：</p>
<p>　　（1）一个包说明，即package语句，包说明是可选的。</p>
<p>　　（2）任意多个引入语句，即import语句。</p>
<p>　　（3）类和接口说明。</p>
<p>　　这些语句必须按一定的次序出现，即，引入语句必须出现在所有的类说明之前，如果使用了包说明，则它必须出现在类说明和引入语句之前。</p>
<p>　　例如，下面是正确的语句序列：</p>
<p>　　package Transportation；</p>
<p>　　import jaya.awt.Graphics</p>
<p>　　import jays.applet.Applet；</p>
<p>　　下面是两例错误的语句顺序：</p>
<p>　　import java.aWt.Graphics</p>
<p>　　import java.applet.Applet；</p>
<p>　　package Transportation；</p>
<p>　　该例中在包说明语句之前含有<u><strong>其他</strong></u>语句。</p>
<p>　　package Transportation；</p>
<p>　　package House；</p>
<p>　　import java.applet.Applet；</p>
<p>　　该例中含有两个包说明语句。<a href="http://www.pass4sure.com/HP0-345.html">HP0-345</a>&nbsp;<a href="http://www.pass4sure.com/HP0-634.html">HP0-634</a> <br />
</p>
</pre>
<div id="articlebody">
1.错误提示内容：Can&#8216;t find class HelloworldApp
<p>　　解释：（当键入<u><strong>java</strong></u> HelloWorldApp时发生该错误。）</p>
<p>　　系统找不到名为HelloWorldApp的类文件。一般地，该错误意味着类名拼写和源文件名不一样，系统创建filename.class文件时使用的是类定义的名字，并且区分大小写。</p>
<p>　　例如：</p>
<p>　　class HelloWorldapp（&#8230;）</p>
<p>　　经<u><strong>编译</strong></u>后将创建HelloWorldapp.class类。执行时，也要使用这个名字。发生这个错误时，可以使用文件查看命令Is或dir看看当前目录下是否存在相应的文件，并检查文件名的大小写。</p>
<p>　　2.错误提示内容：In class HelloWorldApp：main must be public and static</p>
<p>　　解释：如果main（）方法的左侧缺少static或public，会发生这个错误。前面已经解释过对main（）方法前面的修饰符有特殊的要求。</p>
<p>　　3.文件中含有的类个数错误</p>
<p>　　解释：按照Java规则，在一个源文件中最多只能定义一个公有类，否则会发生运行时错误。如果一个应用系统中有多个公有类，则要把它们分别放在各自不同的文件中。文件中非公有类的个数不限。</p>
<p>　　4.层次错误</p>
<p>　　解释：一个。java源文件可以含有三个&#8220;顶层&#8221;元素，这三个元素是：</p>
<p>　　（1）一个包说明，即package语句，包说明是可选的。</p>
<p>　　（2）任意多个引入语句，即import语句。<a href="http://www.pass4sure.com/HP0-645.html">HP0-645</a>&nbsp;<a href="http://www.pass4sure.com/HP0-661.html">HP0-661</a></p>
<p>　　（3）类和接口说明。</p>
<p>　　这些语句必须按一定的次序出现，即，引入语句必须出现在所有的类说明之前，如果使用了包说明，则它必须出现在类说明和引入语句之前。</p>
<p>　　例如，下面是正确的语句序列：</p>
<p>　　package Transportation；</p>
<p>　　import jaya.awt.Graphics</p>
<p>　　import jays.applet.Applet；</p>
<p>　　下面是两例错误的语句顺序：</p>
<p>　　import java.aWt.Graphics</p>
<p>　　import java.applet.Applet；</p>
<p>　　package Transportation；</p>
<p>　　该例中在包说明语句之前含有<u><strong>其他</strong></u>语句。</p>
<p>　　package Transportation；</p>
<p>　　package House；</p>
<p>　　import java.applet.Applet；</p>
<p>　　该例中含有两个包说明语句。</p>
</div>
<img src ="http://www.blogjava.net/java2java/aggbug/183079.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/java2java/" target="_blank">java2java</a> 2008-03-01 09:55 <a href="http://www.blogjava.net/java2java/archive/2008/03/01/183079.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA JSP servlet取路径问题总结.... </title><link>http://www.blogjava.net/java2java/archive/2008/01/10/174221.html</link><dc:creator>java2java</dc:creator><author>java2java</author><pubDate>Thu, 10 Jan 2008 03:35:00 GMT</pubDate><guid>http://www.blogjava.net/java2java/archive/2008/01/10/174221.html</guid><wfw:comment>http://www.blogjava.net/java2java/comments/174221.html</wfw:comment><comments>http://www.blogjava.net/java2java/archive/2008/01/10/174221.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/java2java/comments/commentRss/174221.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/java2java/services/trackbacks/174221.html</trackback:ping><description><![CDATA[<div class="item-content">一 JAVA 类中<br />
1。取出指定所在类的路径
<p>class A {<br />
String getPath() {<br />
&nbsp;&nbsp;&nbsp;&nbsp; return this.getClass().getClassLoade<font color="#ff00ff">r<strong>().getSystemResource("A").</strong></font>getPath();<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p>2。取出类ClassLoader的开始路径（执行路径）<br />
//String preUri=this.getClass().getClassLoader<strong><font color="#00ffcc">(</font><font color="#ff33ff">).getResource("").</font></strong>getPath();</p>
<p>比如WebApp的项目，以下的指令得出的结果就是</p>
<p>/D:/project/crFj163Web/web/exploded/WEB-INF/classes/</p>
<p>比如你是纯java的程序，就是你执行java指令的当前路径</p>
<p>3。取出jdk所在的bin目录</p>
<p>//得到当前用户路径，执行路径 System.getProperty(&#8221;user.dir&#8221;)</p>
<p>其中user.dir是一个参数，更多参数请看这里</p>
<p>二、jsp/servlet 中的取路径</p>
<p>以前我们常用getRealPath(),不过这个方法已经不推荐用了。但我们可以使用request.getContextPath().另外还有request.getRequestURL() 或者request.getRequestURI()。下面举例，以建立一个app1的webapp为例</p>
<p>1。request.getContextPath()打印出来的是</p>
<p>/app1</p>
<p>2。request.getRequestURL() 打印出来的是</p>
<p>http://localhost:8080/app1/index.jsp</p>
<p>3。request.getRequestURI() 打印出来的是</p>
<p>/app1/index.jsp</p>
转载（&nbsp;&nbsp;<a href="http://www.pass4sure.com/190-721.html">190-721</a>&nbsp;<a href="http://www.pass4sure.com/000-746.html">000-746</a>&nbsp;）</div>
<img src ="http://www.blogjava.net/java2java/aggbug/174221.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/java2java/" target="_blank">java2java</a> 2008-01-10 11:35 <a href="http://www.blogjava.net/java2java/archive/2008/01/10/174221.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java操作Oracle数据库（建表，插数据，删除）</title><link>http://www.blogjava.net/java2java/archive/2008/01/10/174209.html</link><dc:creator>java2java</dc:creator><author>java2java</author><pubDate>Thu, 10 Jan 2008 02:54:00 GMT</pubDate><guid>http://www.blogjava.net/java2java/archive/2008/01/10/174209.html</guid><wfw:comment>http://www.blogjava.net/java2java/comments/174209.html</wfw:comment><comments>http://www.blogjava.net/java2java/archive/2008/01/10/174209.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/java2java/comments/commentRss/174209.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/java2java/services/trackbacks/174209.html</trackback:ping><description><![CDATA[&nbsp;<br />
import java.sql.*; <br />
<br />
public class Create { <br />
public Create() { <br />
} <br />
public static void main(String[] args){ <br />
String url = "jdbc:oracle:thin:@10.0.1.3:1521:SDCDB"; <br />
String query = "CREATE TABLE MYFIRST" + "(id INT,name CHAR(10))"; <br />
String sql="insert into MYFIRST values(''1'',''liming'')"; <br />
String sql1="insert into MYFIRST values(''2'',''mm'')"; <br />
String sql2="delete MYFIRST where id=2"; <br />
try <br />
{ <br />
Class.forName("oracle.jdbc.driver.OracleDriver"); <br />
Connection conn = DriverManager.getConnection(url, "test", "test"); <br />
Statement stmt = conn.createStatement(); <br />
stmt.executeUpdate(query); <br />
stmt.executeUpdate(sql); <br />
stmt.executeUpdate(sql1); <br />
stmt.executeUpdate(sql2); <br />
System.out.println("Create Success!"); <br />
stmt.close(); <br />
conn.close(); <br />
} <br />
catch(java.lang.ClassNotFoundException e){ <br />
System.err.print(e.getMessage()); <br />
} <br />
catch(SQLException ex){ <br />
System.out.println("\n***SQLException caught ***\n"); <br />
} <br />
} <br />
} 
<img src ="http://www.blogjava.net/java2java/aggbug/174209.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/java2java/" target="_blank">java2java</a> 2008-01-10 10:54 <a href="http://www.blogjava.net/java2java/archive/2008/01/10/174209.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java认证考试介绍</title><link>http://www.blogjava.net/java2java/archive/2008/01/07/173249.html</link><dc:creator>java2java</dc:creator><author>java2java</author><pubDate>Mon, 07 Jan 2008 02:11:00 GMT</pubDate><guid>http://www.blogjava.net/java2java/archive/2008/01/07/173249.html</guid><wfw:comment>http://www.blogjava.net/java2java/comments/173249.html</wfw:comment><comments>http://www.blogjava.net/java2java/archive/2008/01/07/173249.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/java2java/comments/commentRss/173249.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/java2java/services/trackbacks/173249.html</trackback:ping><description><![CDATA[&nbsp;Sun Java认证分为两个级别：Sun 认证Java程序员和Sun 认证Java开发员。Sun 认证Java程序员考试内容涉及Java所有相关知识、编程概念及applet开发技巧。Sun认证Java程序员考试旨在考察您通过应用软件分配进行复杂编程的能力。之后还要测试您完成编程所需的知识。每次考试都包括65道以上的多项选择题，时间大约为90分钟。考试合格后由Sun公司颁发的国际通用的Java程序员证书。 <br />
<br />
　　 Java程序员 <br />
　　 概述：本课程使学员掌握如何使用标准Java Development kit（JDK）开发应用程序和applets。在本课程中您将学会Java语言的语法。如何使用Java来创建图形用户接口（GUI），事件处理机制，例外处理，通过设计与开发各种Java程序来获得实际的编程经验。您也将学到文件输入/输出（I/O），多线程和网络的知识。 <br />
<br />
　　 目标：本课程完成后，您将具备以下能力： <br />
　　 使用Java编程语言创建Java应用程序和applets <br />
　　 定义和描述垃圾搜集，安全性和Java虚拟机（JVM） <br />
　　 描述和使用Java语言面向对象的特点；开发图形用户接口（GUI） <br />
　　 利用Java支持的多种布局管理 <br />
　　 描述和使用 Java的事件处理模式 <br />
　　 使用Java语言的鼠标输入，文本，窗口和菜单窗口部件 <br />
　　 使用Java的例外处理来控制程序执行和定义用户自己的例外事件 <br />
　　 使用Java语言的先进的面向对象特点，包括方法重载，方法覆盖，抽象类，接口，final，static和访问控制；实现文件的输入输出（I/O） <br />
　　 使用Java语言内在的线程模式来控制多线程 <br />
　　 使用Java的Sockets机制进行网络通信 <br />
　　 预备知识：熟悉DOS操作，用过WINDOWS并能用C或C++编程。 <br />
<br />
　　 Java开发员 <br />
　　 概述：本课程将提供给学员设计资料服务器应用法的实际设计方法，学员将使用Java声音、图形、网络通讯等接口，编写与服务器相连接的Java应用程度，通过本课程学员还能学到如何在Java程序中调用本机用其它计算机语言编写的程序 <a href="http://www.pass4sure.com/117-102.html">117-102</a>&nbsp;<a href="http://www.pass4sure.com/117-301.html">117-301</a>&nbsp;<a href="http://www.pass4sure.com/190-721.html">190-721</a>&nbsp;。 <br />
<br />
　　 本课程是为熟悉Java语言结构及语法的程序员而设立的。以便他们能在本课程中获得开发复杂的、产品级的Java应用技术。 <br />
　　 目标：在学完本课程后，学员将能够： <br />
　　 设计和开发Java GUI <br />
　　 设计和开发动画Java应用程序 <br />
　　 掌握了Java网络编程技术 <br />
　　 懂得了JDBC-API的基本结构 <br />
　　 知道UNIX与Windows NT互连有哪些技术问题 <br />
　　 能够解释在Java程序中调用其它语言所编写的程序的方法与步骤 <br />
<br />
　　 Sun认证Java程序员考试（JDK1.1）由一门考试组成，可以用来测试考生对Java语言的掌握程度。考生可以使用考试大纲（exam objectives）作为准备考试的工具。 <br />
　　 为了保证Sun客户使用的是Sun的最新技术，Sun Educational Services已经把Sun认证Java程序员考试更新为JDK1.1。 <br />
<br />
　　 考试细则 <br />
　　 考试名称： <br />
　　 The Sun Certified Java Programmer for JDK 1.1 <br />
　　 考试号： <br />
　　 310-022（IBM考生除外），310-023（只对IBM考生） <br />
　　 推荐教材： <br />
　　 SL-275 &#8220;Java Programming（UNIX）&#8221; <br />
　　 SL-276&#8220;Java Progrmming（Windows 95）&#8221; <br />
　　 JTL-SL-275&#8220;Java Tutor:Java Programming Library&#8221; <br />
　　 题数：60 <br />
　　 考题类型：多选/简答 <br />
　　 通过分数： 70% <br />
　　 考试时间： 2小时 <br />
　　 考试费用： $150
<img src ="http://www.blogjava.net/java2java/aggbug/173249.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/java2java/" target="_blank">java2java</a> 2008-01-07 10:11 <a href="http://www.blogjava.net/java2java/archive/2008/01/07/173249.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java学习之路：不走弯路，就是捷径 </title><link>http://www.blogjava.net/java2java/archive/2008/01/07/173248.html</link><dc:creator>java2java</dc:creator><author>java2java</author><pubDate>Mon, 07 Jan 2008 02:09:00 GMT</pubDate><guid>http://www.blogjava.net/java2java/archive/2008/01/07/173248.html</guid><wfw:comment>http://www.blogjava.net/java2java/comments/173248.html</wfw:comment><comments>http://www.blogjava.net/java2java/archive/2008/01/07/173248.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/java2java/comments/commentRss/173248.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/java2java/services/trackbacks/173248.html</trackback:ping><description><![CDATA[在ChinaITLAB导师制辅导中，笔者发现问得最多的问题莫过于"如何学习编程？JAVA该如何学习？"。类似的问题回答多了，难免会感觉厌烦，就萌生了写下本文的想法。到时候再有人问起类似的问题，我可以告诉他（她），请你去看看《JAVA学习之路》。拜读过台湾蔡学镛先生的《JAVA夜未眠》，有些文章如《JAVA学习之道》等让我们确实有共鸣，本文题目也由此而来。 <br />
　　软件开发之路是充满荆棘与挑战之路,也是充满希望之路。JAVA学习也是如此，没有捷径可走。梦想像《天龙八部》中虚竹一样被无崖子醍醐灌顶而轻松获得一甲子功力，是很不现实的。每天仰天大叫"天神啊，请赐给我一本葵花宝典吧"，殊不知即使你获得了葵花宝典，除了受自宫其身之苦外，你也不一定成得了"东方不败"，倒是成"西方失败"的几率高一点。 <br />
　　"不走弯路，就是捷径"，佛经说的不无道理。 <br />
　　1．如何学习程序设计？ <br />
　　JAVA是一种平台，也是一种程序设计语言，如何学好程序设计不仅仅适用于JAVA，对C++等其他程序设计语言也一样管用。有编程高手认为，JAVA也好C也好没什么分别，拿来就用。为什么他们能达到如此境界？我想是因为编程语言之间有共通之处，领会了编程的精髓，自然能够做到一通百通。如何学习程序设计理所当然也有许多共通的地方。 <br />
　　1.1　培养兴趣 <br />
　　兴趣是能够让你坚持下去的动力。如果只是把写程序作为谋生的手段的话，你会活的很累，也太对不起自己了。多关心一些行业趣事，多想想盖茨。不是提倡天天做白日梦，但人要是没有了梦想，你觉得有味道吗？可能像许多深圳本地农民一样，打打麻将，喝喝功夫茶，拜拜财神爷；每个月就有几万十几万甚至更多的进帐，凭空多出个"食利阶层"。你认为，这样有味道吗？有空多到一些程序员论坛转转，你会发现，他们其实很乐观幽默，时不时会冒出智慧的火花。 <br />
　　1.2　慎选程序设计语言 <br />
　　男怕入错行，女怕嫁错郎。初学者选择程序设计语言需要谨慎对待。软件开发不仅仅是掌握一门编程语言了事，它还需要其他很多方面的背景知识。软件开发也不仅仅局限于某几个领域，而是已经渗透到了各行各业几乎每一个角落。 <br />
　　如果你对硬件比较感兴趣，你可以学习C语言/汇编语言，进入硬件开发领域。如果你对电信的行业知识及网络比较熟悉，你可以在C/C++等之上多花时间，以期进入电信软件开发领域。如果你对操作系统比较熟悉，你可以学习C/Linux等等,为Linux内核开发/驱动程序开发/嵌入式开发打基础。如果你想介入到应用范围最广泛的应用软件开发（包括电子商务电子政务系统）的话，你可以选择J2EE或.NET，甚至LAMP组合。每个领域要求的背景知识不一样。做应用软件需要对数据库等很熟悉。总之，你需要根据自己的特点来选择合适你的编程语言。 <br />
　　1.3　要脚踏实地,快餐式的学习不可取 <br />
　　先分享一个故事。 <br />
　　有一个小朋友，他很喜欢研究生物学，很想知道那些蝴蝶如何从蛹壳里出来，变成蝴蝶便会飞。&nbsp;&nbsp;有一次，他走到草原上面看见一个蛹，便取了回家，然后看着，过了几天以后，这个蛹出了一条裂痕，看见里面的蝴蝶开始挣扎，想抓破蛹壳飞出来。&nbsp;&nbsp;这个过程达数小时之久，蝴蝶在蛹里面很辛苦地拼命挣扎，怎么也没法子走出来。这个小孩看着看着不忍心，就想不如让我帮帮它吧，便随手拿起剪刀在蛹上剪开，使蝴蝶破蛹而出。&nbsp;&nbsp;但蝴蝶出来以后，因为翅膀不够力，变得很臃肿，飞不起来。 <br />
　　这个故事给我们的启示是：欲速则不达。 <br />
　　浮躁是现代人最普遍的心态，能怪谁？也许是贫穷落后了这么多年的缘故，就像当年的大跃进一样，都想大步跨入共产主义社会。现在的软件公司、客户、政府、学校、培训机构等等到处弥漫着浮躁之气。就拿笔者比较熟悉的深圳IT培训行业来说吧，居然有的打广告宣称"参加培训，100%就业"，居然报名的学生不少，简直是藐视天下程序员。社会环境如是，我们不能改变，只能改变自己,闹市中的安宁，弥足珍贵。许多初学者C++/JAVA没开始学，立马使用VC/JBuilder,会使用VC/JBuilder开发一个Hello&nbsp;&nbsp;World程序，就忙不迭的向世界宣告，"我会软件开发了"，简历上也大言不惭地写上"精通VC/JAVA"。结果到软件公司面试时要么被三两下打发走了，要么被驳的体无完肤，无地自容。到处碰壁之后才知道捧起《C++编程思想》《JAVA编程思想》仔细钻研，早知如此何必当初呀。 <br />
　　"你现在讲究简单方便，你以后的路就长了"，好象也是佛经中的劝戒。 <br />
　　1.4　多实践,快实践 <br />
　　彭端淑的《为学一首示子侄》中有穷和尚与富和尚的故事。 <br />
　　从前，四川边境有两个和尚，一个贫穷，一个有钱。一天，穷和尚对富和尚说："我打算去南海朝圣，你看怎么样？"富和尚说："这里离南海有几千里远，你靠什么去呢？"穷和尚说："我只要一个水钵，一个饭碗就够了。"富和尚为难地说："几年前我就打算买条船去南海，可至今没去成，你还是别去吧！"&nbsp;&nbsp;一年以后，富和尚还在为租赁船只筹钱，穷和尚却已经从南海朝圣回来了。 <br />
　　这个故事可解读为：任何事情，一旦考虑好了，就要马上上路，不要等到准备周全之后，再去干事情。假如事情准备考虑周全了再上路的话，别人恐怕捷足先登了。软件开发是一门工程学科，注重的就是实践，"君子动口不动手"对软件开发人员来讲根本就是错误的，他们提倡"动手至上"，但别害怕，他们大多温文尔雅，没有暴力倾向，虽然有时候蓬头垢面的一副"比尔盖茨"样。有前辈高人认为，学习编程的秘诀是：编程、编程、再编程，笔者深表赞同。不仅要多实践，而且要快实践。我们在看书的时候，不要等到你完全理解了才动手敲代码，而是应该在看书的同时敲代码，程序运行的各种情况可以让你更快更牢固的掌握知识点。 <br />
　　1.5　多参考程序代码 <br />
　　程序代码是软件开发最重要的成果之一，其中渗透了程序员的思想与灵魂。许多人被《仙剑奇侠传》中凄美的爱情故事感动,悲剧的结局更有一种缺憾美。为什么要以悲剧结尾？据说是因为写《仙剑奇侠传》的程序员失恋而安排了这样的结局，他把自己的感觉融入到游戏中，却让众多的仙剑迷扼腕叹息。 <br />
　　多多参考代码例子，对JAVA而言有参考文献[4.3],有API类的源代码(JDK安装目录下的src.zip文件)，也可以研究一些开源的软件或框架。 <br />
　　1.6　加强英文阅读能力 <br />
　　对学习编程来说，不要求英语,&nbsp;&nbsp;但不能一点不会,。最起码像JAVA&nbsp;&nbsp;API文档(参考文献[4.4])这些东西还是要能看懂的,连猜带懵都可以；旁边再开启一个"金山词霸"。看多了就会越来越熟练。在学JAVA的同时学习英文，一箭双雕多好。另外好多软件需要到英文网站下载，你要能够找到它们，这些是最基本的要求。英语好对你学习有很大的帮助。口语好的话更有机会进入管理层，进而可以成为剥削程序员的"周扒皮"。 <br />
　　1.7　万不得已才请教别人 <br />
　　笔者在ChinaITLab网校的在线辅导系统中解决学生问题时发现，大部分的问题学生稍做思考就可以解决。请教别人之前，你应该先回答如下几个问题。 <br />
　　你是否在google中搜索了问题的解决办法？ <br />
　　你是否查看了JAVA&nbsp;&nbsp;API文档？ <br />
　　你是否查找过相关书籍？ <br />
　　你是否写代码测试过？ <br />
　　如果回答都是"是"的话，而且还没有找到解决办法，再问别人不迟。要知道独立思考的能力对你很重要。要知道程序员的时间是很宝贵的。 <br />
　　1.8　多读好书 <br />
　　书中自有颜如玉。比尔?盖茨是一个饱读群书的人。虽然没有读完大学，但九岁的时候比尔?盖茨就已经读完了所有的百科全书，所以他精通天文、历史、地理等等各类学科，可以说比尔?盖茨不仅是当今世界上金钱的首富，而且也可以称得上是知识的巨富。 <br />
　　笔者在给学生上课的时候经常会给他们推荐书籍，到后来学生实在忍无可忍开始抱怨，"天呐，这么多书到什么时候才能看完了"，"学软件开发，感觉上了贼船"。这时候，我的回答一般是，"别着急，什么时候带你们去看看我的书房，到现在每月花在技术书籍上的钱400元，这在软件开发人员之中还只能够算是中等的"，学生当场晕倒。（注：这一部分学生是刚学软件开发的） <br />
　　对于在JAVA开发领域的好书在笔者另外一篇文章中会专门点评。该文章可作为本文的姊妹篇。 <br />
　　1.9　使用合适的工具 <br />
　　工欲善其事必先利其器。软件开发包含各种各样的活动，需求收集分析、建立用例模型、建立分析设计模型、编程实现、调试程序、自动化测试、持续集成等等，没有工具帮忙可以说是寸步难行。工具可以提高开发效率，使软件的质量更高BUG更少。组合称手的武器。到飞花摘叶皆可伤人的境界就很高了，无招胜有招，手中无剑心中有剑这样的境界几乎不可企及。在笔者另外一篇文章中会专门阐述如何选择合适的工具（该文章也可作为本文的姊妹篇）。 <br />
　　2．软件开发学习路线 <br />
　　两千多年的儒家思想孔孟之道，中庸的思想透入骨髓，既不冒进也不保守并非中庸之道，而是找寻学习软件开发的正确路线与规律。 <br />
　　从软件开发人员的生涯规划来讲，我们可以大致分为三个阶段，软件工程师&#8594;软件设计师&#8594;架构设计师或项目管理师。不想当元帅的士兵不是好士兵，不想当架构设计师或项目管理师的程序员也不是好的程序员。我们应该努力往上走。让我们先整理一下开发应用软件需要学习的主要技术。 <br />
　　A．基础理论知识，如操作系统、编译原理、数据结构与算法、计算机原理等，它们并非不重要。如不想成为计算机科学家的话，可以采取"用到的时候再来学"的原则。 <br />
　　B．一门编程语言，现在基本上都是面向对象的语言，JAVA/C++/C#等等。如果做WEB开发的话还要学习HTML/JavaScript等等。 <br />
　　C．一种方法学或者说思想，现在基本都是面向对象思想（OOA/OOD/设计模式）。由此而衍生的基于组件开发CBD/面向方面编程AOP等等。 <br />
　　D．一种关系型数据库，ORACLE/SqlServer/DB2/MySQL等等 <br />
　　E．一种提高生产率的IDE集成开发环境JBuilder/Eclipse/VS.NET等。 <br />
　　F．一种UML建模工具，用ROSE/VISIO/钢笔进行建模。 <br />
　　G．一种软件过程，RUP/XP/CMM等等，通过软件过程来组织软件开发的众多活动，使开发流程专业化规范化。当然还有其他的一些软件工程知识。 <br />
　　H．项目管理、体系结构、框架知识。 <br />
　　正确的路线应该是：B&#8594;C&#8594;E&#8594;F&#8594;G&#8594;H。 <br />
　　还需要补充几点： <br />
　　1）．对于A与C要补充的是，我们应该在实践中逐步领悟编程理论与编程思想。新技术虽然不断涌现，更新速度令人眼花燎乱雾里看花；但万变不离其宗，编程理论与编程思想的变化却很慢。掌握了编程理论与编程思想你就会有拨云见日之感。面向对象的思想在目前来讲是相当关键的，是强势技术之一，在上面需要多投入时间，给你的回报也会让你惊喜。 <br />
　　2）．对于数据库来说是独立学习的，这个时机就由你来决定吧。 <br />
　　3）．编程语言作为学习软件开发的主线，而其余的作为辅线。 <br />
　　4）．软件工程师着重于B、C、E、&nbsp;&nbsp;D；软件设计师着重于B、C、E、&nbsp;&nbsp;D、F；架构设计师着重于C、F、H。 <br />
　　3．如何学习JAVA? <br />
　　3.1&nbsp;&nbsp;JAVA学习路线 <br />
　　3.1.1&nbsp;&nbsp;基础语法及JAVA原理 <br />
　　基础语法和JAVA原理是地基，地基不牢靠，犹如沙地上建摩天大厦，是相当危险的。学习JAVA也是如此，必须要有扎实的基础，你才能在J2EE、J2ME领域游刃有余。参加SCJP（SUN公司认证的JAVA程序员）考试不失为一个好方法，原因之一是为了对得起你交的1200大洋考试费，你会更努力学习，原因之二是SCJP考试能够让你把基础打得很牢靠，它要求你跟JDK一样熟悉JAVA基础知识；但是你千万不要认为考过了SCJP就有多了不起，就能够获得软件公司的青睐，就能够获取高薪，这样的想法也是很危险的。获得"真正"的SCJP只能证明你的基础还过得去，但离实际开发还有很长的一段路要走。 <br />
　　3.1.2&nbsp;&nbsp;OO思想的领悟 <br />
　　掌握了基础语法和JAVA程序运行原理后，我们就可以用JAVA语言实现面向对象的思想了。面向对象，是一种方法学;是独立于语言之外的编程思想;是CBD基于组件开发的基础;属于强势技术之一。当以后因工作需要转到别的面向对象语言的时候，你会感到特别的熟悉亲切，学起来像喝凉水这么简单。 <br />
　　使用面向对象的思想进行开发的基本过程是： <br />
　　●调查收集需求。 <br />
　　●建立用例模型。 <br />
　　●从用例模型中识别分析类及类与类之间的静态动态关系，从而建立分析模型。 <br />
　　●细化分析模型到设计模型。 <br />
　　●用具体的技术去实现。 <br />
　　●测试、部署、总结。 <br />
　　3.1.3&nbsp;&nbsp;基本API的学习 <br />
　　进行软件开发的时候，并不是什么功能都需要我们去实现，也就是经典名言所说的"不需要重新发明轮子"。我们可以利用现成的类、组件、框架来搭建我们的应用，如SUN公司编写好了众多类实现一些底层功能，以及我们下载过来的JAR文件中包含的类,我们可以调用类中的方法来完成某些功能或继承它。那么这些类中究竟提供了哪些方法给我们使用？方法的参数个数及类型是？类的构造器需不需要参数？总不可能SUN公司的工程师打国际长途甚至飘洋过海来告诉你他编写的类该如何使用吧。他们只能提供文档给我们查看，JAVA&nbsp;&nbsp;DOC文档（参考文献4.4）就是这样的文档，它可以说是程序员与程序员交流的文档。 <br />
　　基本API指的是实现了一些底层功能的类，通用性较强的API，如字符串处理/输入输出等等。我们又把它成为类库。熟悉API的方法一是多查JAVA&nbsp;&nbsp;DOC文档（参考文献4.4），二是使用JBuilder/Eclipse等IDE的代码提示功能。 <br />
　　3.1.4&nbsp;&nbsp;特定API的学习 <br />
　　JAVA介入的领域很广泛，不同的领域有不同的API，没有人熟悉所有的API，对一般人而言只是熟悉工作中要用到的API。如果你做界面开发，那么你需要学习Swing/AWT/SWT等API；如果你进行网络游戏开发，你需要深入了解网络API/多媒体API/2D3D等；如果你做WEB开发，就需要熟悉Servlet等API啦。总之，需要根据工作的需要或你的兴趣发展方向去选择学习特定的API。 <br />
　　3.1.5&nbsp;&nbsp;开发工具的用法 <br />
　　在学习基础语法与基本的面向对象概念时，从锻炼语言熟练程度的角度考虑，我们推荐使用的工具是Editplus/JCreator+JDK,这时候不要急于上手JBuilder/Eclipse等集成开发环境，以免过于关注IDE的强大功能而分散对JAVA技术本身的注意力。过了这一阶段你就可以开始熟悉IDE了。 <br />
　　程序员日常工作包括很多活动，编辑、编译及构建、调试、单元测试、版本控制、维持模型与代码同步、文档的更新等等，几乎每一项活动都有专门的工具，如果独立使用这些工具的话，你将会很痛苦，你需要在堆满工具的任务栏上不断的切换，效率很低下，也很容易出错。在JBuilder、Eclipse等IDE中已经自动集成编辑器、编译器、调试器、单元测试工具JUnit、自动构建工具ANT、版本控制工具CVS、DOC文档生成与更新等等，甚至可以把UML建模工具也集成进去，又提供了丰富的向导帮助生成框架代码，让我们的开发变得更轻松。应该说IDE发展的趋势就是集成软件开发中要用到的几乎所有工具。 <br />
　　从开发效率的角度考虑，使用IDE是必经之路，也是从一个学生到一个职业程序员转变的里程碑。 <br />
　　JAVA开发使用的IDE主要有Eclipse、JBuilder、JDeveloper、NetBeans等几种；而Eclipse、JBuilder占有的市场份额是最大的。JBuilder在近几年来一直是JAVA集成开发环境中的霸主，它是由备受程序员尊敬的Borland公司开发，在硝烟弥漫的JAVA&nbsp;&nbsp;IDE大战中,以其快速的版本更新击败IBM的Visual&nbsp;&nbsp;Age&nbsp;&nbsp;for&nbsp;&nbsp;JAVA等而成就一番伟业。IBM在Visual&nbsp;&nbsp;Age&nbsp;&nbsp;for&nbsp;&nbsp;JAVA上已经无利可图之下，干脆将之贡献给开源社区，成为Eclipse的前身，真所谓"柳暗花明又一村"。浴火重生的Eclipse以其开放式的插件扩展机制、免费开源获得广大程序员（包括几乎所有的骨灰级程序员）的青睐，极具发展潜力。 <br />
　　3.1.6&nbsp;&nbsp;学习软件工程 <br />
　　对小型项目而言，你可能认为软件工程没太大的必要。随着项目的复杂性越来越高，软件工程的必要性才会体现出来。参见"软件开发学习路线"小节。 <br />
　　3.2学习要点 <br />
　　确立的学习路线之后，我们还需要总结一下JAVA的学习要点，这些要点在前文多多少少提到过，只是笔者觉得这些地方特别要注意才对它们进行汇总，不要嫌我婆婆妈妈啊。 <br />
　　3.2.1勤查API文档 <br />
　　当程序员编写好某些类，觉得很有成就感,想把它贡献给各位苦难的同行。这时候你要使用"javadoc"工具（包含在JDK中）生成标准的JAVA&nbsp;&nbsp;DOC文档,供同行使用。J2SE/J2EE/J2ME的DOC文档是程序员与程序员交流的工具，几乎人手一份，除了菜鸟之外。J2SE&nbsp;&nbsp;DOC文档官方下载地址：<a href="http://java.sun.com/j2se/1.5.0/download.jsp" target="_blank">http://java.sun.com/j2se/1.5.0/download.jsp</a>，你可以到google搜索CHM版本下载。也可以在线查看：<a href="http://java.sun.com/j2se/1.5.0/docs/api/index.html" target="_blank">http://java.sun.com/j2se/1.5.0/docs/api/index.html</a> 。<br />
　　对待DOC文档要像毛主席语录，早上起床念一遍，吃饭睡觉前念一遍。 <br />
　　当需要某项功能的时候，你应该先查相应的DOC文档看看有没有现成的实现，有的话就不必劳神费心了直接用就可以了，找不到的时候才考虑自己实现。使用步骤一般如下： <br />
　　●找特定的包，包一般根据功能组织。 <br />
　　●找需要使用类，类命名规范的话我们由类的名字可猜出一二。 <br />
　　●选择构造器，大多数使用类的方式是创建对象。 <br />
　　●选择你需要的方法。 <br />
　　3.2.2&nbsp;&nbsp;查书/google-&gt;写代码测试-&gt;查看源代码-&gt;请教别人 <br />
　　当我们遇到问题的时候该如何解决？ <br />
　　这时候不要急着问别人，太简单的问题，没经过思考的问题，别人会因此而瞧不起你。可以先找找书，到google中搜一下看看，绝大部分问题基本就解决了。而像"某些类/方法如何使用的问题"，DOC文档就是答案。对某些知识点有疑惑是，写代码测试一下，会给你留下深刻的印象。而有的问题，你可能需要直接看API的源代码验证你的想法。万不得已才去请教别人。 <br />
　　3.2.3学习开源软件的设计思想 <br />
　　JAVA领域有许多源代码开放的工具、组件、框架，JUnit、ANT、Tomcat、Struts、Spring、Jive论坛、PetStore宠物店等等多如牛毛。这些可是前辈给我们留下的瑰宝呀。入宝山而空手归，你心甘吗？对这些工具、框架进行分析，领会其中的设计思想，有朝一日说不定你也能写一个XXX框架什么的，风光一把。分析开源软件其实是你提高技术、提高实战能力的便捷方法。 <br />
　　3.2.4&nbsp;&nbsp;规范的重要性 <br />
　　没有规矩，不成方圆。这里的规范有两层含义。第一层含义是技术规范，多到<a href="http://www.jcp.org/" target="_blank">http://www.jcp.org</a>下载jsrxxx规范，多读规范，这是最权威准确最新的教材。第二层含义是编程规范，如果你使用了大量的独特算法，富有个性的变量及方法的命名方式；同时，没给程序作注释，以显示你的编程功底是多么的深厚。这样的代码别人看起来像天书，要理解谈何容易，更不用说维护了，必然会被无情地扫入垃圾堆。java编码规范到此查看或下载 http://java.sun.com/docs/codeconv/，中文的也有，啊，还要问我在哪，请参考3.2.2节。 <br />
　　3.2.5&nbsp;&nbsp;不局限于JAVA <br />
　　很不幸，很幸运，要学习的东西还有很多。不幸的是因为要学的东西太多且多变，没时间陪老婆家人或女朋友，导致身心疲惫，严重者甚至导致抑郁症。幸运的是别人要抢你饭碗绝非易事，他们或她们需要付出很多才能达成心愿。 <br />
　　JAVA不要孤立地去学习，需要综合学习数据结构、OOP、软件工程、UML、网络编程、数据库技术等知识，用横向纵向的比较联想的方式去学习会更有效。如学习JAVA集合的时候找数据结构的书看看；学JDBC的时候复习数据库技术；采取的依然是"需要的时候再学"的原则 <a href="http://www.pass4sure.com/000-834.html">000-834</a>&nbsp;<a href="http://www.pass4sure.com/000-861.html">000-861</a>&nbsp;。 <br />
　　4．结束语 <br />
　　需要强调的是，学习软件开发确实有一定的难度，也很辛苦，需要付出很多努力，但千万不要半途而废。本文如果能对一直徘徊在JAVA神殿之外的朋友有所帮助的话，笔者也欣慰了。哈哈，怎么听起来老气横秋呀？没办法，在电脑的长期辐射之下，都快变成小老头了。最后奉劝各位程序员尤其是MM程序员，完成工作后赶快远离电脑，据《胡播乱报》报道，电脑辐射会在白皙的皮肤上面点缀一些小黑点，看起来鲜艳无比&#8230;&#8230; <br />
<img src ="http://www.blogjava.net/java2java/aggbug/173248.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/java2java/" target="_blank">java2java</a> 2008-01-07 10:09 <a href="http://www.blogjava.net/java2java/archive/2008/01/07/173248.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Java程序的加密和反加密</title><link>http://www.blogjava.net/java2java/archive/2008/01/03/172532.html</link><dc:creator>java2java</dc:creator><author>java2java</author><pubDate>Thu, 03 Jan 2008 09:51:00 GMT</pubDate><guid>http://www.blogjava.net/java2java/archive/2008/01/03/172532.html</guid><wfw:comment>http://www.blogjava.net/java2java/comments/172532.html</wfw:comment><comments>http://www.blogjava.net/java2java/archive/2008/01/03/172532.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/java2java/comments/commentRss/172532.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/java2java/services/trackbacks/172532.html</trackback:ping><description><![CDATA[<p>首先我们来看看Java程序的反加密，也就是通常所说的Crack过程，只有明白了这个过程，我们才能有效的对我们的程序进行加密。</p>
<p>通常我们得到的Java程序的Crack包有两种，一种属于KeyGen（注册码生成器）、一种属于替换修改；</p>
<p>我们先看第一种，当我们找到一个应用程序的KeyGen的时候我们总是很佩服那个做出KeyGen的人，觉得他很厉害，但是你仔细分析一下，为什么他能做出KeyGen呢？只有<br />
他对这个Java程序的加密算法了解的非常清楚；这种人有哪些呢？一个是那个公司里面的人，那不可能，除非内讧，还又呢，就是猜想，反推，这个可能吗？呵呵，更不可能，那这个算法从哪里来呢？呵呵，往往泄漏秘密的就是秘密本身&#8230;&#8230;回过头来想想，Java应用程序怎么知道你输入的注册码是否正确呢？呵呵，那你就该从应用程序入手&#8230;&#8230;<br />
得到的它的加密算法，自然KeyGen就不在话下了&#8230;&#8230;（但是这也有列外，如果它是用的公钥秘钥对加密的，就没有办法喽，只能用第二种方法。）</p>
<p>这种办法只适合对付只要一个注册号，别的什么都不要的情况，经典代表Borland JBuilder &amp; Optimizeit Suite</p>
<p>再看第二种，为什么要用替换修改？我们是修改了那部分呢？不用想，肯定是License验证的部分，为什么我们不像上面的方法那样找加密算法呢？原因有两种：（1）使用上面的办法搞不定；（2）Java程序不仅要Key，还有其他的License配置；遇到这种情况，我们只要找到用于License验证的类，进行修改替换就行了。</p>
<p>这种办法使用于任何情况，经典代表BEA WebLogic</p>
<p>经过上面的分析，我们的问题就集中了，关键就是怎么找到用于License验证的部分或加密算法的部分，我们需要3个工具：一个是Sun公司提供的标准JVM：），一个是你<br />
的耐心和细心：），一个是Jad（经典Java反编译工具）。</p>
<p>第一步是定位，这也是最关键的一步，我们这里以Together For JBuilder Edition为例，启动Together，先看看长什么样子？喔，上来就问我要License；Ok，<br />
每关系，退出；找到Together的启动Bat文件，找到它的启动命令：java .....，OK，在Java启动的时候给一个参数：&#8220; -Xrunhprof:cpu=times&#8221;，保存，在启动，还是要<br />
License，退出，这个时候，我们可以发现，在这个目录下多了一个&#8220;java.hprof.txt&#8221;文件，打开一看，就是我要的JVM的Dump文件，好多内容啊，没关系，慢慢看来。</p>
<p>我们可以看见这个文件里面有好多熟悉的东西啊：java.*/com.sun.*/javax.*等等，但这个不是我们关心的，我们要的是com.togethersoft.*或者是一些没有包名的zd.d等等。（这里插一句，几乎所有的Java应用程序都会混淆的，其实混淆的原理也很简单，我们后面再说。）先找找有没有License有关的，Serach一下，嘿嘿，果然，474行：com.togethersoft.together.impl.ide.license.LicenseSetup.execute([DashoPro-V2-050200]:Unknown line)，Ok上那堆classpath中的Jar包里面找一下吧（推荐用WinRAR），找到了之后用Jad反编译，一看，这个没有混淆，但是用了一个zae的类，这个看名字就知道混淆过了，先不理它，再看看下面一句IdeLicenseAccess.setLicense(zae1)，Ok接着找到IdeLicenseAccess，哈哈，就这点名堂，所有的License验证都是走的这个类，面向对象的思想不错，呵呵：）</p>
<p>定位定完了，接下来的事情就是按猜想的方法修改这两个类，屏蔽掉LicenseSetup里面execute方法的实际内容，修改IdeLicenseAccess，让多有的验证都返回true，然后编译，替换；不要高兴太早，这还没有完呢，要有责任心！！启动Together，果然，这下不要License了，有启动画面，进去了，但是一片灰色，怎么回事，一看控制台，一堆错，没关系，就怕不出错，查找根源，还有一个IdeLicenseUtil类出了问题，再反编译，修改，替换；这下搞定了。再启动，测试一下，OK <a href="http://www.pass4sure.com/MB7-222.html">MB7-222</a>&nbsp;<a href="http://www.pass4sure.com/70-210.html">70-210</a>&nbsp;<a href="http://www.pass4sure.com/1Y0-327.html">1Y0-327</a>&nbsp;。</p>
<p>就这样，一个Java应用程序搞定了。看看其实也很简单。</p>
<p>再来说说混淆，大家可能都知道没有经过混淆的Java的Class反编译回来连方法和变量的名字都不会变，这是什么原因呢？这就要追述到Class文件的结构了，简单来说，Class文件种包含又一个常数池（constant pool）这个里面就存放了变量和方法的名称等一下和Class相关的东西，我们通常所说的混淆就是用一种工具把这个常数池里面的东东弄的胡涂一点，这样就能骗过反编译器和你，呵呵：）这就是为什么有时候反编译回来的东西编译不过去的原因。</p>
<p>再回过头来说说Java程序的加密；从上面的两种方法来看，Java程序似乎是没有什么完美的办法进行加密的，其实不然，我们必须遵循一些原则，才能有效的保护你的产品。</p>
<p>原则一，尽量使用公钥和秘钥对进行加密；<br />
原则二，不要在加密验证的部分使用面向对象思想：）把验证的方法写在程序的各个角落，并标注为private final void，让编译器替你处理成内联方法；<br />
原则三，尽可能的大幅度混淆：）找个好点的混淆器</p>
<img src ="http://www.blogjava.net/java2java/aggbug/172532.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/java2java/" target="_blank">java2java</a> 2008-01-03 17:51 <a href="http://www.blogjava.net/java2java/archive/2008/01/03/172532.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java中的易混问题收集 </title><link>http://www.blogjava.net/java2java/archive/2008/01/03/172530.html</link><dc:creator>java2java</dc:creator><author>java2java</author><pubDate>Thu, 03 Jan 2008 09:50:00 GMT</pubDate><guid>http://www.blogjava.net/java2java/archive/2008/01/03/172530.html</guid><wfw:comment>http://www.blogjava.net/java2java/comments/172530.html</wfw:comment><comments>http://www.blogjava.net/java2java/archive/2008/01/03/172530.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/java2java/comments/commentRss/172530.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/java2java/services/trackbacks/172530.html</trackback:ping><description><![CDATA[<br />
<br />
<font color="red">第一，final, finally, finalize的区别.</font><br />
<br />
final 修饰符（关键字）如果一个类被声明为final，意味着它不能再派生出新的子类，不能作为父类被继承。因此一个类不能既被声明为 abstract的，又被声明为final的。将变量或方法声明为final，<strong></strong>可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值，而在以后的引用中只能读取，不可修改。被声明为final的方法也同样只能使用，不能重载 <br />
<br />
finally 再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常，那么相匹配的 catch 子句就会执行，然后控制就会进入 finally 块（如果有的话）。 <br />
finalize 方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的，因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。 <br />
<br />
<font color="red">第二，Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类，是否可以implements(实现)interface(接口)? </font><br />
<br />
匿名的内部类是没有名字的内部类。不能extends(继承) 其它类，但一个内部类可以作为一个接口，由另一个内部类实现。 <br />
<br />
<font color="red">第三，Static Nested Class 和 Inner Class的不同，说得越多越好</font><br />
Nested Class （一般是C++的说法），Inner Class (一般是JAVA的说法)。Java内部类与C++嵌套类最大的不同就在于是否有指向外部的引用上。具体可见http: //www.frontfree.net/articles/services/view.asp?id=704&amp;page=1 <br />
注： 静态内部类（Inner Class）意味着1创建一个static内部类的对象，不需要一个外部类对象，2不能从一个static内部类的一个对象访问一个外部类对象 <br />
<br />
<font color="red">第四，&amp;和&amp;&amp;的区别。</font><br />
<br />
&amp;是位运算符。&amp;&amp;是布尔逻辑运算符。 <br />
<br />
<font color="red">第五，HashMap和Hashtable的区别。</font><br />
<br />
都属于Map接口的类，实现了将惟一键映射到特定的值上。 <br />
HashMap 类没有分类或者排序。它允许一个 null 键和多个 null 值。 <br />
Hashtable 类似于 HashMap，但是不允许 null 键和 null 值。它也比 HashMap 慢，因为它是同步的。 <br />
<br />
<font color="red">第六，Collection 和 Collections的区别。</font> <br />
Collections是个java.util下的类，它包含有各种有关集合操作的静态方法。 <br />
Collection是个java.util下的接口，它是各种集合结构的父接口。 <br />
<br />
<font color="red">第七，什么时候用assert。 </font><br />
断言是一个包含布尔表达式的语句，在执行这个语句时假定该表达式为 true。如果表达式计算为 false，那么系统会报告一个 Assertionerror。它用于调试目的： <br />
assert(a &gt; 0); // throws an Assertionerror if a &lt;= 0 <br />
断言可以有两种形式： <br />
assert Expression1 ; <br />
assert Expression1 : Expression2 ; <br />
Expression1 应该总是产生一个布尔值。 <br />
Expression2 可以是得出一个值的任意表达式。这个值用于生成显示更多调试信息的 String 消息。 <br />
断言在默认情况下是禁用的。要在编译时启用断言，需要使用 source 1.4 标记： <br />
javac -source 1.4 Test.java <br />
要在运行时启用断言，可使用 -enableassertions 或者 -ea 标记。 <br />
要在运行时选择禁用断言，可使用 -da 或者 -disableassertions 标记。 <br />
要系统类中启用断言，可使用 -esa 或者 -dsa 标记。还可以在包的基础上启用或者禁用断言。 <br />
可以在预计正常情况下不会到达的任何位置上放置断言。断言可以用于验证传递给私有方法的参数。不过，断言不应该用于验证传递给公有方法的参数，因为不管是否启用了断言，公有方法都必须检查其参数。不过，既可以在公有方法中，也可以在非公有方法中利用断言测试后置条件。另外，断言不应该以任何方式改变程序的状态。 <br />
<br />
<font color="red">第八，GC是什么? 为什么要有GC? (基础)。</font><br />
<br />
GC是垃圾收集器。Java 程序员不用担心内存管理，因为垃圾收集器会自动进行管理。要请求垃圾收集，可以调用下面的方法之一： <br />
System.gc() <br />
Runtime.getRuntime().gc() <br />
<br />
<font color="red">第九，String s = new String("xyz");创建了几个String Object? </font><br />
<br />
两个对象，一个是&#8220;xyx&#8221;,一个是指向&#8220;xyx&#8221;的引用对象s。 <br />
<br />
<font color="red">第十，Math.round(11.5)等於多少? Math.round(-11.5)等於多少? </font><br />
<br />
Math.round(11.5)返回（long）12，Math.round(-11.5)返回（long）-11; <br />
<br />
<font color="red">第十一，short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错? </font><br />
<br />
short s1 = 1; s1 = s1 + 1;有错，s1是short型，s1+1是int型,不能显式转化为short型。可修改为s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正确。 <br />
<br />
<font color="red">第十二，sleep() 和 wait() 有什么区别? 搞线程的最爱 </font><br />
sleep()方法是使线程停止一段时间的方法。在sleep 时间间隔期满后，线程不一定立即恢复执行。这是因为在那个时刻，其它线程可能正在运行而且没有被调度为放弃执行，除非(a)&#8220;醒来&#8221;的线程具有更高的优先级 <br />
(b)正在运行的线程因为其它原因而阻塞。 <br />
wait()是线程交互时，如果线程对一个同步对象x 发出一个wait()调用，该线程会暂停执行，被调对象进入等待状态，直到被唤醒或等待时间到。 <br />
<br />
<font color="red">第十三，Java有没有goto? </font><br />
Goto java中的保留字，现在没有在java中使用。 <br />
<br />
<font color="red">第十四，数组有没有length()这个方法? String有没有length()这个方法？</font> <br />
<br />
数组没有length()这个方法，有length的属性。 <br />
String有有length()这个方法。 <br />
<br />
<font color="red">第十五，Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型? </font><br />
<br />
方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现，重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数，我们说该方法被重写 (Overriding)。子类的对象使用这个方法时，将调用子类中的定义，对它而言，父类中的定义如同被&#8220;屏蔽&#8221;了。如果在一个类中定义了多个同名的方法，它们或有不同的参数个数或有不同的参数类型，则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。 <br />
<br />
<font color="red">第十六，Set里的元素是不能重复的，那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别? </font><br />
<br />
Set里的元素是不能重复的，那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等。 <br />
equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖，为的是当两个分离的对象的内容和类型相配的话，返回真值。 <br />
<br />
<font color="red">第十七，给我一个你最常见到的runtime exception。</font> <br />
ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, <br />
ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFORMatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException&nbsp; <a href="http://www.pass4sure.com/190-802.html">190-802</a>&nbsp;<a href="http://www.pass4sure.com/000-834.html">000-834</a>&nbsp;<a href="http://www.pass4sure.com/000-861.html">000-861</a>&nbsp;<a href="http://www.pass4sure.com/117-102.html">117-102</a>&nbsp;<a href="http://www.pass4sure.com/117-301.html">117-301</a>&nbsp;<a href="http://www.pass4sure.com/190-721.html">190-721</a><br />
<br />
<font color="red">第十八，error和exception有什么区别? </font><br />
error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。 <br />
exception 表示一种设计或实现问题。也就是说，它表示如果程序运行正常，从不会发生的情况。 <br />
<br />
<font color="red">第十九，List, Set, Map是否继承自Collection接口? </font><br />
List，Set是 <br />
<br />
Map不是 <br />
<br />
<font color="red">第二十，abstract class和interface有什么区别? </font><br />
<br />
声明方法的存在而不去实现它的类被叫做抽象类（abstract class），它用于要创建一个体现某些基本行为的类，并为该类声明方法，但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量，其类型是一个抽象类，并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现，否则它们也是抽象类为。取而代之，在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。 <br />
接口（interface）是抽象类的变体。在接口中，所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的，没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似，除了该实现类不能从接口定义中继承行为。当类实现特殊接口时，它定义（即将程序体给予）所有这种接口的方法。然后，它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类，它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换，instanceof 运算符可以用来决定某对象的类是否实现了接口。 <br />
<br />
<font color="red">第二十一，abstract的method是否可同时是static,是否可同时是native，是否可同时是synchronized? </font><br />
<br />
都不能 <br />
<br />
<font color="red">第二十二，接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)? </font><br />
接口可以继承接口。抽象类可以实现(implements)接口，抽象类是否可继承实体类，但前提是实体类必须有明确的构造函数。 <br />
<br />
<font color="red">第二十三，启动一个线程是用run()还是start()? </font><br />
启动一个线程是调用start()方法，使线程所代表的虚拟处理机处于可运行状态，这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。 <br />
<br />
<font color="red">第二十四，构造器Constructor是否可被override? </font>构造器Constructor不能被继承，因此不能重写Overriding，但可以被重载Overloading。 <br />
<br />
<font color="red">第二十五，是否可以继承String类? </font><br />
String类是final类故不可以继承。 <br />
<br />
<font color="red">第二十六，当一个线程进入一个对象的一个synchronized方法后，其它线程是否可进入此对象的其它方法? </font><br />
不能，一个对象的一个synchronized方法只能由一个线程访问。 <br />
<br />
<font color="red">第二十七，try {}里有一个return语句，那么紧跟在这个try后的finally {}里的code会不会被执行，什么时候被执行，在return前还是后? </font><br />
<br />
会执行，在return前执行。 <br />
<br />
<font color="red">第二十八，编程题: 用最有效率的方法算出2乘以8等於几? </font><br />
<br />
有C背景的程序员特别喜欢问这种问题。 <br />
<br />
2 &lt;&lt; 3 <br />
<br />
<font color="red">第二十九，两个对象值相同(x.equals(y) == true)，但却可有不同的hash code，这句话对不对? </font><br />
不对，有相同的hash code。 <br />
<br />
<font color="red">第三十，当一个对象被当作参数传递到一个方法后，此方法可改变这个对象的属性，并可返回变化后的结果，那么这里到底是值传递还是引用传递? </font><br />
<br />
是值传递。Java 编程语言只由值传递参数。当一个对象实例作为一个参数被传递到方法中时，参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变，但对象的引用是永远不会改变的。 <br />
<br />
<font color="red">第三十一，swtich是否能作用在byte上，是否能作用在long上，是否能作用在String上? </font><br />
<br />
switch（expr1）中，expr1是一个整数表达式。因此传递给 switch 和 case 语句的参数应该是 int、 short、 char 或者 byte。long,string 都不能作用于swtich。 <br />
<br />
<font color="red">第三十二，编程题: 写一个Singleton出来。</font><br />
<br />
Singleton模式主要作用是保证在Java应用程序中，一个类Class只有一个实例存在。 <br />
一般Singleton模式通常有几种种形式: <br />
第一种形式: 定义一个类，它的构造函数为private的，它有一个static的private的该类变量，在类初始化时实例话，通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。 <br />
public class Singleton { <br />
　　private Singleton(){} <br />
　　//在自己内部定义自己一个实例，是不是很奇怪？ <br />
　　//注意这是private 只供内部调用 <br />
　　private static Singleton instance = new Singleton(); <br />
　　//这里提供了一个供外部访问本class的静态方法，可以直接访问　　 <br />
　　public static Singleton getInstance() { <br />
　　　　return instance; 　　 <br />
　　 } <br />
} <br />
第二种形式: <br />
public class Singleton { <br />
　　private static Singleton instance = null; <br />
　　public static synchronized Singleton getInstance() { <br />
　　//这个方法比上面有所改进，不用每次都进行生成对象，只是第一次　　　 　 <br />
　　//使用时生成实例，提高了效率！ <br />
　　if (instance==null) <br />
　　　　instance＝new Singleton(); <br />
return instance; 　　} <br />
} <br />
其他形式: <br />
定义一个类，它的构造函数为private的，所有方法为static的。 <br />
一般认为第一种形式要更加安全些 <br />
<br />
<font color="red">第三十三 Hashtable和HashMap </font><br />
Hashtable继承自Dictionary类，而HashMap是Java1.2引进的Map interface的一个实现 <br />
<br />
HashMap允许将null作为一个entry的key或者value，而Hashtable不允许 <br />
<br />
还有就是，HashMap把Hashtable的contains方法去掉了，改成containsvalue和containsKey。因为contains方法容易让人引起误<strong></strong>解。 <br />
<br />
最大的不同是，Hashtable的方法是Synchronize的，而HashMap不是，在 <br />
多个线程访问Hashtable时，不需要自己为它的方法实现同步，而HashMap <br />
就必须为之提供外同步。 <br />
<br />
Hashtable和HashMap采用的hash/rehash算法都大概一样，所以性能不会有很大的差异。 
<img src ="http://www.blogjava.net/java2java/aggbug/172530.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/java2java/" target="_blank">java2java</a> 2008-01-03 17:50 <a href="http://www.blogjava.net/java2java/archive/2008/01/03/172530.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java技术与XML常见问题之JAX-RPC</title><link>http://www.blogjava.net/java2java/archive/2007/12/09/166441.html</link><dc:creator>java2java</dc:creator><author>java2java</author><pubDate>Sun, 09 Dec 2007 06:47:00 GMT</pubDate><guid>http://www.blogjava.net/java2java/archive/2007/12/09/166441.html</guid><wfw:comment>http://www.blogjava.net/java2java/comments/166441.html</wfw:comment><comments>http://www.blogjava.net/java2java/archive/2007/12/09/166441.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/java2java/comments/commentRss/166441.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/java2java/services/trackbacks/166441.html</trackback:ping><description><![CDATA[问题. 什么是 Java API for XML-Based RPC（JAX-RPC）？ <br />
　　答. Java API for XML-Based RPC（JAX-RPC）使得 Java 技术开发人员使用基于 XML 的 RPC 功能构建 Web 应用程序和 Web 服务，此功能遵循 SOAP（简单对象访问协议，Simple Object Access Protocol）1.1 规范。<br />
　　问题. JAX-RPC 如何使用 SOAP ？ <br />
　　答. 请参考 JSR-101 。 <br />
　　问题. 什么是 RPC？ <br />
　　答. RPC 代表远程过程调用（remote procedure call），它是能使客户端执行其他系统中程序的一种机制。RPC 机制常用于分布式客户端/服务器模型。服务器将服务定义为一系列过程，可供远程客户端调用。<br />
　　问题. XML 如何与 RPC 相关联？ <br />
　　答. 远程过程调用是由基于 XML 的协议来表示的，比如 SOAP 。除了定义信封结构和编码规则之外，SOAP 规范还定义了远程过程调用和响应的表示惯例。<br />
　　问题. 对于 Web 服务，JAX-RPC 必须做哪些工作？ <br />
　　答. 一个基于 XML 的 RPC 服务器应用程序可以定义、描述和导出一个的 Web 服务，如同基于 RPC 的服务一样。WSDL（Web 服务描述语言，Web Service Description Language&nbsp;&nbsp;<a href="http://www.pass4sure.com/HP0-922.html">HP0-922</a>&nbsp;）定义了一种 XML 格式，将服务描述为一组消息操作的端点集合。通过使用 JAX-RPC API ，开发人员可以用 WSDL 描述来实现客户端和服务。<br />
　　问题. 客户端与 JAX-RPC 服务之间采用什么交互模式？ <br />
　　答. 有以下三种不同的模式：<br />
　　1. 同步请求-响应（Synchronous Request-Response）：客户端调用远程程序并阻塞，直到它收到一个返回值或异常。 <br />
　　2. 单向 RPC（One-Way RPC）：客户端调用远程过程，但自身不阻塞或等待直到收到一个返回值。JAX-RPC 客户端的运行时系统可能会抛出异常。 <br />
　　3. 非阻塞 RPC 调用（Non-Blocking RPC Invocation <a href="http://www.pass4sure.com/190-823.html">190-823</a>&nbsp;<a href="http://www.pass4sure.com/1Y0-614.html">1Y0-614</a>）：客户端调用远程过程，并继续处理同一个线程的内容而不等待返回值。此后，客户端通过阻塞来接受返回值或轮询返回值，以此来处理远程方法的返回。 <br />
　　问题. 远程方法调用或响应能否传送服务内容信息？ <br />
　　答. 是的。例如它可能会传送唯一的事务标识符或数字签名。<br />
　　问题. 为什么 xrpcc 没有生成 WSDL 文件？ <br />
　　答. xrpcc 工具实际上可以生成 WSDL 文件，但由于设计失误，如果不指定 &#8211;keep 选项，该文件会同源文件一起被删除。您可以使用 &#8211;keep 选项让 xrpcc 不删除 WSDL 或 .java 源文件。如果您使用 &#8211;s sourcepath 选项，所有源文件将被放置在 sourcepath 目录中，然后您可以很容易地删除它们。 WSDL 文件将被放置在当前目录或由 &#8211;d 选项指定的目录中。 
<img src ="http://www.blogjava.net/java2java/aggbug/166441.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/java2java/" target="_blank">java2java</a> 2007-12-09 14:47 <a href="http://www.blogjava.net/java2java/archive/2007/12/09/166441.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java图像处理技巧四则</title><link>http://www.blogjava.net/java2java/archive/2007/11/26/163145.html</link><dc:creator>java2java</dc:creator><author>java2java</author><pubDate>Mon, 26 Nov 2007 05:47:00 GMT</pubDate><guid>http://www.blogjava.net/java2java/archive/2007/11/26/163145.html</guid><wfw:comment>http://www.blogjava.net/java2java/comments/163145.html</wfw:comment><comments>http://www.blogjava.net/java2java/archive/2007/11/26/163145.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/java2java/comments/commentRss/163145.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/java2java/services/trackbacks/163145.html</trackback:ping><description><![CDATA[<p>&nbsp;下面代码中用到的sourceImage是一个已经存在的Image对象 </p>
<p>图像剪切<br />
对于一个已经存在的Image对象，要得到它的一个局部图像，可以使用下面的步骤： </p>
<p>&nbsp;//import java.awt.*; <br />
//import java.awt.image.*; <br />
Image croppedImage; <br />
ImageFilter cropFilter; <br />
CropFilter =new CropImageFilter(25,30,75,75);　//四个参数分别为图像起点坐标和宽高，即CropImageFilter(int x,int y,int width,int height)，详细情况请参考API <br />
CroppedImage= Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(sourceImage.getSource(),cropFilter));</p>
<p><br />
如果是在Component的子类中使用，可以将上面的Toolkit.getDefaultToolkit().去掉。FilteredImageSource是一个ImageProducer对象。 <br />
图像缩放 <br />
对于一个已经存在的Image对象，得到它的一个缩放的Image对象可以使用Image的getScaledInstance方法： </p>
<p>Image scaledImage=sourceImage. getScaledInstance(100,100, Image.SCALE_DEFAULT);　//得到一个100X100的图像 <br />
Image doubledImage=sourceImage. getScaledInstance(sourceImage.getWidth(this)*2,sourceImage.getHeight(this)*2, Image.SCALE_DEFAULT);　//得到一个放大两倍的图像,这个程序一般在一个swing的组件中使用，而类Jcomponent实现了图像观察者接口ImageObserver，所有可以使用this。 <br />
//其它情况请参考API</p>
<p><br />
灰度变换<br />
下面的程序使用三种方法对一个彩色图像进行灰度变换，变换的效果都不一样。一般而言，灰度变换的算法是将象素的三个颜色分量使用R*0.3+G*0.59＋B*0.11得到灰度值，然后将之赋值给红绿蓝，这样颜色取得的效果就是灰度的。另一种就是取红绿蓝三色中的最大值作为灰度值。java核心包也有一种算法，但是没有看源代码，不知道具体算法是什么样的，效果和上述不同。 </p>
<p>&nbsp;GrayFilter.java <br />
@author :<a href="http://www.tiffanyin.com/">tiffanyin</a> <br />
email:cherami@163.netimport java.awt.image.*; <br />
public class GrayFilter extends RGBImageFilter { <br />
int modelStyle; <br />
public GrayFilter() { <br />
modelStyle=GrayModel.CS_MAX; <br />
canFilterIndexColorModel=true; <br />
} <br />
public GrayFilter(int style) { <br />
modelStyle=style; <br />
canFilterIndexColorModel=true; <br />
} <br />
public void setColorModel(ColorModel cm) { <br />
if (modelStyle==GrayModel <br />
else if (modelStyle==GrayModel <br />
} <br />
public int filterRGB(int x,int y,int pixel) { <br />
return pixel; <br />
} <br />
} <br />
&nbsp;GrayFilter.java <br />
@author:tiffanyin&nbsp; <br />
email:cherami@163.net <br />
import java.awt.image.*; <br />
public class GrayModel extends ColorModel { <br />
public static final int CS_MAX=0; <br />
public static final int CS_FLOAT=1; <br />
ColorModel sourceModel; <br />
int modelStyle;</p>
<p>public GrayModel(ColorModel sourceModel) { <br />
super(sourceModel.getPixelSize()); <br />
this.sourceModel=sourceModel; <br />
modelStyle=0; <br />
} </p>
<p>public GrayModel(ColorModel sourceModel,int style) { <br />
super(sourceModel.getPixelSize()); <br />
this.sourceModel=sourceModel; <br />
modelStyle=style; <br />
}</p>
<p>public void setGrayStyle(int style) { <br />
modelStyle=style; <br />
} </p>
<p>protected int getGrayLevel(int pixel) { <br />
if (modelStyle==CS_MAX) { <br />
return Math.max(sourceModel.getRed(pixel),Math.max(sourceModel.getGreen(pixel),sourceModel.getBlue(pixel))); <br />
} <br />
else if (modelStyle==CS_FLOAT){ <br />
return (int)(sourceModel.getRed(pixel)*0.3+sourceModel.getGreen(pixel)*0.59+sourceModel.getBlue(pixel)*0.11); <br />
} <br />
else { <br />
return 0; <br />
} <br />
} </p>
<p>public int getAlpha(int pixel) { <br />
return sourceModel.getAlpha(pixel); <br />
} </p>
<p>public int getRed(int pixel) { <br />
return getGrayLevel(pixel); <br />
} </p>
<p>public int getGreen(int pixel) { <br />
return getGrayLevel(pixel); <br />
} </p>
<p>public int getBlue(int pixel) { <br />
return getGrayLevel(pixel); <br />
} </p>
<p>public int getRGB(int pixel) { <br />
int gray=getGrayLevel(pixel); <br />
return (getAlpha(pixel)&lt;&lt;24)+(gray&lt;&lt;16)+(gray&lt;&lt;8)+gray; <br />
} <br />
}</p>
<p><br />
如果你有自己的算法或者想取得特殊的效果，你可以修改类GrayModel的方法getGrayLevel()。 <br />
色彩变换<br />
根据上面的原理，我们也可以实现色彩变换，这样的效果就很多了。下面是一个反转变换的例子： </p>
<p><br />
/* ReverseColorModel.java*/ <br />
&nbsp; @author: <a href="http://www.tiffanyin.com/">tiffanyin</a>&nbsp; <br />
/*email:cherami@163.net*/ <br />
import java.awt.image.*; <br />
public class ReverseColorModel extends ColorModel { <br />
ColorModel sourceModel; <br />
public ReverseColorModel(ColorModel sourceModel) { <br />
super(sourceModel.getPixelSize()); <br />
this.sourceModel=sourceModel; <br />
} </p>
<p>public int getAlpha(int pixel) { <br />
return sourceModel.getAlpha(pixel); <br />
} </p>
<p>public int getRed(int pixel) { <br />
return ~sourceModel.getRed(pixel); <br />
} </p>
<p>public int getGreen(int pixel) { <br />
return ~sourceModel.getGreen(pixel); <br />
} </p>
<p>public int getBlue(int pixel) { <br />
return ~sourceModel.getBlue(pixel); <br />
}</p>
<p>public int getRGB(int pixel) { <br />
return (getAlpha(pixel)&lt;&lt;24)+(getRed(pixel)&lt;&lt;16)+(getGreen(pixel)&lt;&lt;8)+getBlue(pixel); <br />
} <br />
} <br />
/* ReverseColorModel.java*/ <br />
/*@author:tiffanyin */ <br />
/*email:cherami@163.net*/ <br />
import java.awt.image.*; <br />
public class ReverseFilter extends RGBImageFilter { <br />
public ReverseFilter() { <br />
canFilterIndexColorModel=true; <br />
} </p>
<p>public void setColorModel(ColorModel cm) { <br />
substituteColorModel(cm,new ReverseColorModel(cm)); <br />
} </p>
<p>public int filterRGB(int x,int y,int pixel) { <br />
return pixel; <br />
} <br />
}</p>
<p><br />
要想取得自己的效果，需要修改ReverseColorModel.java中的三个方法，getRed、getGreen、getBlue。 <br />
下面是上面的效果的一个总的演示程序。 </p>
<p><br />
/*GrayImage.java*/ <br />
<a>/*@author</a>: <a href="http://www.tiffanyin.com/">tiffanyin</a>&nbsp;*/ <br />
/*email:cherami@163.net*/ <br />
import java.awt.*; <br />
import java.awt.image.*; <br />
import javax.swing.*; <br />
import java.awt.color.*; <br />
public class GrayImage extends JFrame{ <br />
Image source,gray,gray3,clip,bigimg; <br />
BufferedImage bimg,gray2; <br />
GrayFilter filter,filter2; <br />
ImageIcon ii; <br />
ImageFilter cropFilter; <br />
int iw,ih; </p>
<p>public GrayImage() { <br />
ii=new ImageIcon(\"images/11.gif\"); <br />
source=ii.getImage(); <br />
iw=source.getWidth(this); <br />
ih=source.getHeight(this); <br />
filter=new GrayFilter(); <br />
filter2=new GrayFilter(GrayModel.CS_FLOAT); <br />
gray=createImage(new FilteredImageSource(source.getSource(),filter)); <br />
gray3=createImage(new FilteredImageSource(source.getSource(),filter2)); <br />
cropFilter=new CropImageFilter(5,5,iw-5,ih-5); <br />
clip=createImage(new FilteredImageSource(source.getSource(),cropFilter)); <br />
bigimg=source.getScaledInstance(iw*2,ih*2,Image.SCALE_DEFAULT); <br />
MediaTracker mt=new MediaTracker(this); <br />
mt.addImage(gray,0); <br />
try { <br />
mt.waitForAll(); <br />
} catch (Exception e) { <br />
} <br />
} </p>
<p>public void paint(Graphics g) { <br />
Graphics2D g2=(Graphics2D)g; <br />
bimg=new BufferedImage(iw, ih, BufferedImage.TYPE_INT_RGB); <br />
Graphics2D srcG = bimg.createGraphics(); <br />
RenderingHints rhs = g2.getRenderingHints(); <br />
srcG.setRenderingHints(rhs); <br />
srcG.drawImage(source, 0, 0, null); <br />
ColorSpace graySpace=ColorSpace.getInstance(ColorSpace.CS_GRAY); <br />
ColorConvertOp op=new ColorConvertOp(graySpace,rhs); <br />
gray2=new BufferedImage(iw, ih, BufferedImage.TYPE_INT_RGB); <br />
op.filter(bimg,gray2); <br />
g2.drawImage(source,40,40,this); <br />
g2.drawImage(gray,80,40,this); <br />
g2.drawImage(gray2,120,40,this); <br />
g2.drawImage(gray3,160,40,this); <br />
g2.drawImage(clip,40,80,this); <br />
g2.drawImage(bigimg,80,80,this); <br />
} </p>
<p>public void update(Graphics g) { <br />
paint(g); <br />
} </p>
<p>public static void main(String args[]) { <br />
GrayImage m=new GrayImage(); <br />
m.setSize(400,400); <br />
m.setVisible(true); <br />
} <br />
}<br />
</p>
<img src ="http://www.blogjava.net/java2java/aggbug/163145.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/java2java/" target="_blank">java2java</a> 2007-11-26 13:47 <a href="http://www.blogjava.net/java2java/archive/2007/11/26/163145.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java学习过程中应该理解的一些重点内容</title><link>http://www.blogjava.net/java2java/archive/2007/11/19/161554.html</link><dc:creator>java2java</dc:creator><author>java2java</author><pubDate>Mon, 19 Nov 2007 03:34:00 GMT</pubDate><guid>http://www.blogjava.net/java2java/archive/2007/11/19/161554.html</guid><wfw:comment>http://www.blogjava.net/java2java/comments/161554.html</wfw:comment><comments>http://www.blogjava.net/java2java/archive/2007/11/19/161554.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/java2java/comments/commentRss/161554.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/java2java/services/trackbacks/161554.html</trackback:ping><description><![CDATA[数值类型： <br />
<br />
虽然是面向对象的语言，但是在使用上数值类型还是必不可少的，如果在C的学习中已经掌握了C的数值计算和转换规则，那我想这里应该没有什么问题，只有两点需要注意：1、14.0这样的浮点常量被认为是double型，只有加上f后缀才是float型的；2、整数常量说起来被认为是int型，但是在编译时，可以认为编译器将其看作能表示该数的最小数值，因此byte b = 100;不会报错。 <br />
<br />
引用类型： <br />
<br />
其实所谓引用类型在C++中已有体现，就是传参的时候有一种引用类型，从C来考虑，它就是一个指针，只不过，我们不能对它进行指针上的硬操作。所以这里的重点是：1、Java里所有的对象都是在堆中生成的，所以需要类似指针的东西指向它，那就是引用；2、我们通过引用操作的是引用所指向的对象，除了赋值操作外，应该就没有什么操作是针对引用本身的了，这一点是C的指针与Java的引用区别所在。 <br />
<br />
类和对象： <br />
<br />
这是一个大块，有很多东西，不展开说了，就说几个重点：1、类方法、类属性与成员方法、成员属性在加载、初始化、使用上的异同；2、在构造函数中，this()和super()的用法；3、子类的加载过程、初始化过程和构造过程；4、方法的重载和覆写；5、覆写所引出的多态问题。(注意：多态之应用在方法上，对属性没有作用) <br />
<br />
函数调用的参数传递： <br />
<br />
如果把引用类型所记录的地址值，就看作是引用类型变量的值的话，那么，Java的所有方法调用的时候，都是采用的值传递??数值类型传数值，引用类型传地址。 <br />
<br />
IO流： <br />
<br />
与C比起来，Java的输入输出，尤其是输入是非常麻烦的，也许是因为出于面向对象的考虑吧？不知道。Java提供了很多的IO流，但是我们并不必将各种IO都搞清楚，我们只需要了解字节流与字符流各有什么功能，字符流是如何在字节流之上构造的，几乎所有的字符流构造的时候都是建立在一个已有的字节流的基础上的，并且它的这种设计使得我们可以像套管子一样，将IO流一节一节套起来，直到得到我们想使用的IO对象(例：BufferedReader的使用)。在我们以后使用的时候，我们可以再去查API，主要要看的几个类是：FileReader、FileWriter、BufferedReader，再配合上System.out对象，对于文本的输入、输出来说，就足够用了，其他的没有必要看那么多，用的时候再看了。 <br />
<br />
容器： <br />
<br />
个人认为，这是Java编程的一大利器，常用的类是：ArrayList(List)作为可变长数组、HashMap(Map)用来建立查找表，Set很少用，只在HashMap的使用中连带用过一些。通过对这两个类的熟悉，能够将List、Set和Map三大类的基本用法掌握。另外它的几个辅助类要掌握：Iterator和Collections。Collections类提供容器的一些通用工具，比如排序。而说到排序，就牵扯出了比较器：Comparator。能够熟练使用Comparator类，可以让你为自己的需求和自己的类定制排序方案。 <br />
<br />
AWT和SWING： <br />
<br />
个人认为，Java在图形界面的制作上有着非常好的封装性，我以前曾经试图学过MFC，MFC在生成图形界面的时候会帮助你生成一些代码，然后让你在这些代码的指定位置添加代码以实现功能，我这个人有个习惯，如果让我看到了一些东西，那么我不搞清除为什么这么写，就不会往下走，看到那许多代码，自然就想弄清楚那些是什么，结果引出来好多知识，后来我才知道其中有些是调用WinAPI，结果我到现在还是不会用MFC。这里并不是贬低MFC，我相信MFC有其过人之处，只不过个人认为它的封装性做得不好，暴露出了太多东西，也许能够提高灵活性，不过，可能我跟它无缘:(。在这方面Java就做得不错，给你一个类，你用就是了，它将图形界面的低层实现隐藏的很好，将其作为一个对象给你，而你只需要在这个对象上修修改改，挺方便的。 <br />
<br />
作为初学者，我觉得AWT的重点在于它的几个Listener的用法，还有布局格式，然后就是那许多的Component的用处和用法。 <br />
<br />
不过，因为我个人使用的原因，所以至今AWT和SWING都用得很少，所以这方面也就不便多说了，抱歉。写这些并不是告诉大家怎么解决问题，因为每一个都有很多可写，只是希望能给初学者一点参考，希望能够帮助初学者们有的放矢地看书.&nbsp;(&nbsp;转载<a href="http://www.pass4sure.com/920-432.html">920-432</a>&nbsp;<a href="http://www.pass4sure.com/920-553.html">920-553</a>&nbsp;)<br />
<img src ="http://www.blogjava.net/java2java/aggbug/161554.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/java2java/" target="_blank">java2java</a> 2007-11-19 11:34 <a href="http://www.blogjava.net/java2java/archive/2007/11/19/161554.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>