Java常见问题集锦

: 如何设置 Java 2(JDK1.2) 的环境变量 ?

:
Java 2
安装后 , 需要设置 PATH JAVA_HOME 环境变量 . JDK1.1 不同的是 : 设置好 JAVA_HOME 环境变量后 ,JVM 将自动搜索系统类库以及用户的当前路径 .

Java 2
环境变量的设置如下例所示 :


Solaris
平台 : setenv JAVA_HOME Java2 的安装路径

setenv PATH $JAVA_HOME/bin:${PATH}

Windows
平台 : set JAVA_HOME=Java2 的安装路径

set PATH=$JAVA_HOMEbin;%PATH%


: 哪些 Java 集成开发工具支持 Java 2?

:
目前流行的 Java 集成开发环境 , Inprise JBuilder,Symantec Visual Cafe, Sybase PowerJ, 都支持 Java 2.


: 如果在 Netscape IE 浏览器中运行 Java applet 时出现了错误 , 如何确定错误范围 ?

:
java applet 在浏览器中运行时 , 使用的是浏览器本身的缺省 JVM. 而不同浏览器对 JDK 的支持程度也不尽相同 . 因此 , Netscape IE 浏览器中运行 Java applet 出现了错误 , 建议使用 JDK 提供的工具 appletviewer Sun 公司的 Hotjava 浏览器来测试该 applet, 以确定错误的产生是与浏览器相关 .

如果 applet appletviewer Hotjava 中运行一切正常 , 则错误的产生是由于浏览 器不完全兼容 JDK 而引起的 . 此时 , 解决方法可以是使用 Hotjava 浏览器或者安装 Sun 公司的 Java Plugin.

如果 applet Hotjava 浏览器或 appletviewer 中运行即发生错误 , 则应当根据错误 提示检查 applet 程序 .


: 当用 JDBC 向数据库中插入数据或从数据库中提取数据时 , 为何有时中文字符会显示为乱码 ?

:
这个问题的实现通常与各个 JDBC driver 的实现有关 . 目前大多数 JDBC driver 采用本地编码格式来传输中文字符 , 例如中文字符 "0x4175" 会被转成 "0x41" "0x75" 进行传输 . 因此我们需要对 JDBC driver 返回的字符以及要发给 JDBC driver 的字符进行转换 .

当用 JDBC driver 向数据库中插入数据时 , 需要先将 Unicode 转成 native code; JDBC driver 从数据库中查询数据时 , 则需要将 native code 转换成 Unicode. 下面给出了这两种转换的实现 :


String native2Unicode(String s) {

if (s == null || s.length() == 0) {

return null;

}

byte[] buffer = new byte[s.length()];

for (int i = 0; i s.length(); i++) { if (s.charAt(i)>= 0x100) {

c = s.charAt(i);

byte []buf = (""+c).getBytes();

buffer[j++] = (char)buf[0];

buffer[j++] = (char)buf[1];

}

else {

buffer[j++] = s.charAt(i);

}

}

return new String(buffer, 0, j);

}

除使用以上两个方法之外 , 有些 JDBC driver 如果对 jdbc driver Manager 设置了正确 的字符集属性 , 以上 2 个方法就不需要了 .



: 当用 Servlet 来处理 http 请求并产生返回的 HTML 页面时 , 如何使 HTML 页面中的中文字符能够正常显示 ?

:
javax.servlet.http.HttpResponse
类用于产生返回页面 . 通过 HttpResponse 定义的方法 getOutputStream() 可以获得 ServletOutputStream 的实例 , 这样用户就可以利用 ServletOutputStream.write 方法向输出流中写入返回页面的内容 . 但是 ServletOutputStream 使用的是缺省的编码方式 , 如果要使返回页面中的中文字 符能够正常显示 , 最好显示地指定所用的字符编码方式 . 通常需要构造一个 OutputStreamWriter , 例程如下 :


public void doGet (HttpServletRequest req, HttpServletResponse res)

throws ServletException, IOException

{

res.setContentType("text/html");

ServletOutputStream out = res.getOutputStream();

OutputStreamWriter ow = new OutputStreamWriter(out,"GB2312");

ow.write("
这是测试 ");

ow.flush();

ow.close();

}


: 如何设置 Java WebServer CLASSPATH, 以包含用户的 class 文件 ?

:
有两种方法可以设置 Java WebServer CLASSPATH 环境变量 , 以使用户编写的 Servlet 能够调用用户的 class 文件 .
将用户的 class 文件放到 JavaWebServer_Dir/classes 目录下 , Java WebServer 启动时 ,classes 目录被自动加入到 CLASSPATH 环境变量中了 .
修改 httpd.nojre 文件 , 将用户 class 文件所在的路径名加到 CLASSPATH 环境变量中 .



: 为什么在 Windows 平台上用 Naming.lookup 来获取远程 RMI 对象时会很慢 ?

:
机器的网络设置不正确很可能会引起该问题的发生 .
RMI
使用了 Java 网络类 , 特别是 java.net.InetAddress , 它将查询 TCP/IP 的主机名 , 包括 IP 地址到主机名的映射和主机名到 IP 地址的映射 . Windows 平台 , 这种查询功能 是由本地的 Windows Socket 库来实现的 . 因此延时是发生在 Windows 库中 , 而非 RMI .

如果你的机器设置成使用 DNS, 问题通常是 DNS 服务器查不到主机名 , 你所发现的延时 DNS 查询的延时 . 请尝试将 RMI 通信中涉及到的所有主机名 /IP 地址加到本地文件 winntsystem32driversetchosts windowshosts . 格式如下 :

IP
地址 主机名

如此设置应当可以明显地减少查询所花的时间 .

: 编写 Java application , 如何设置 proxy 的信息 , 以便访问外部网站 ?

:
若在 java application 中访问外部网站 , 首先应设置 proxy 信息 , 样例代码如下 :


import java.util.properties;

.....

Properties sys = System.getProperties();

sys.put("proxySet","true");

sys.put("proxyHost","myHTTP.proxyserver.com");

sys.put("proxyPort","80");

System.setProperties(sys);



u = new URL(website);

connect = (HttpURLConnection)u.openConnection();

.....


: Swing 组件 JList 的列表数据修改了 , 如何通知 JList 改变显示 ?

:
JList
组件有一个单独的显示模式 ListModel 来表示 JList 的显示数据 .
JList
创建以后 ,JList 数据元素的值及数据元素的数量可以动态地改变 .
JList
在它的数据模式 ListModel 中观察数据的改变 . 因此 , 一个 ListModel 的正确实现应当在每次数据发生改变时 , 通知事件的监听者 .
当使用构造函数 JList(Object[]) 创建一个 JList 的实例时 , 系统将自动 创建一个 DefaultListModel 的实例来存储 JList 的显示数据 , 可以调用 DefaultListModel 中定义的简便方法来动态地修改 JList 的数据 , removeElementAt(index),addElement(Object) . DefaultListModel 在修改数据的同时 , 将通知 JList 关于数据的改变 .

: Java applet 中如何实现一个模式对话框 ?

:
Java applet 中实现模式对话框的关键就是在创建一个对话框的时候 要为该对话框指定一个正确的父窗口 . 因为 Applet Panel 类的子类 , 可以作为对话框的父窗口 , 所以首先要获得 applet 所在的窗口 , 作为模式 对话框的父窗口 . 样例代码如下 :


.....

Dialog d = new Dialog( getParentWindow(comp),title);

// comp
applet 上的任意一个组件

....



public void getParentWindow(Component compOnApplet,String title){

Container c = compOnApplet.getParent();

while (c != null) {

if (c instanceof Frame)

return (Frame) c;

c = c.getParent();

}

return null;

}


: Java applet 中如何显示另外一个 HTML 页面 ?

:
通过 java.applet.Applet.getAppletContext() 方法可以获得与该 applet 相关的 AppletContext, AppletContext.showDocument(URL) 方法就可以使 applet 所在的浏览器显示另外一个网页 .


: JDK 实现的签名 applet, 可否在 Netscape IE 中运行 ?

:
JDK 实现的签名 applet, 不可以在 Netscape IE 中运行 , 但是可以在 Hotjava 浏览器中运行 .

不同的浏览器提供了不同的签名 applet 机制 , Netscape 提供了 zigbert 工具和 Capability API, IE 则需要使用 CAB 文件 . 但是 , 无论是 Netscape 工具产生的 签名 applet, 还是用 IE 产生的签名 applet, 都不可以在其它的浏览器中运行 .

如果要使 JDK 产生的签名 applet 能够在 Netscape IE 中运行 , 解决方法是在 Netscape IE 中安装 Java Plugin, 则用 JDK 实现的签名 applet 就可以在这两种 浏览器中运行 .


: JNI 技术可以从 Java 应用中调用 C 程序库 , 但是如何使该 C 程序库可以调用另外的 C 程序库 ?

:
如果一个被 Java 调用的 C 程序库 C1 仍需要调用另外一个 C 程序库 C2, 那么在编译 C1 的时候应当联接程序库 C2, 步骤如下 (Solaris 平台 ):
编写调用 C 库的 Java 文件 , 并编译 .
javac java
文件名


产生 C 程序头文件
javah -jni java
文件名 ( 不带后缀 .java)


编写被 Java 调用的 C 程序 C1.c, 以及被 C1 调用的 C2.c, 并编译 .
cc -G -Iinclude
路径名 C2.c -o libC2.so
cc -G -Iinclude
路径名 -lC2 C1.c -o libC1.so


设置环境变量
setenv LD_LIBRARY_PATH libC1.so,libC2.so
所在路径
:${LD_LIBRARY_PATH}


运行 java 应用


: Java 语言中 , 如何列出 PC 机文件系统中的所有驱动器名 ?

:
Java 2 版本中 ,java.io 包中的 File 类新增加了方法 listRoots() 可以实现这一功能 .


: 为什么 Runtime.exec("ls") 没有任何输出 ?

:
调用 Runtime.exec 方法将产生一个本地的进程 , 并返回一个 Process 子类的实例 , 该实例可用于控制进程或取得进程的相关信息 . 由于调用 Runtime.exec 方法所创建的子进程没有自己的终端或控制台 , 因此该子进程的标准 IO( stdin,stdou,stderr) 都通过 Process.getOutputStream(),Process.getInputStream(), Process.getErrorStream() 方法重定向给它的父进程了 . 用户需要用这些 stream 来向 子进程输入数据或获取子进程的输出 . 所以正确执行 Runtime.exec("ls") 的例程如下 :


try

{

process = Runtime.getRuntime().exec (command);

InputStreamReader ir=newInputStreamReader(process.getInputStream());

LineNumberReader input = new LineNumberReader (ir);

String line;

while ((line = input.readLine ()) != null)

System.out.println(line);

}

catch (java.io.IOException e){

System.err.println ("IOException " + e.getMessage());

}



: 如何产生签名 applet, 以使 applet 能够访问本地资源 ?

:
jdk1.1 , 可以使用 javakey 命令来产生公钥 , 私钥 , 证书和签名的 jar 文件 , 详细资料 请参考 : http://java.sun.com/security/usingJavakey.html java 2 对签名机制做了比较大的改进 , 允许用户更灵活地设置安全权限 .Java 2 提供了三个工具 :keytool,policytool jarsigner 来实现签名 applet. 例如 ,Joe 编写了一个签名 applet:SignedApplet.java, 那么产生一个简单的签名 applet 的过程如下 :


//
产生密钥 , 密钥别名为 joe, 口令为 sign12, 存放在密钥库 joestore

keytool -genkey -alias joe -keypass sign12 -keystore joestore

//
SignedApplet.class 及相关文件打包成 jar 文件

jar cvf SignedAppletDemo.jar

//
利用 keytool 生成的自签名的证书产生签名 applet(jar 文件 )

jarsigner -keystore joestore -signedjar joe.jar SignedAppletDemo.jar joe

//
将自签名证书从 keystore 中输出到文件

keytool -export -keystore joestore -alias joe -file joe.cer



而对于签名 applet 的接受方 Susan, 需要通过如下步骤来安全地执行

Joe
编写的签名 applet:

//
得到 Joe 的证书并将之读入到密钥库中 susanstore

keytool -import -alias joe -file joe.cer -keystore susanstore

//
运行 policytool 产生满足 Susan 要求的 policy 文件

policytool

//
appletviewer 运行之 , 或在浏览器中安装 java plugin 来运行之 .



关于签名 applet Java Plugin 中的部署请参考以下网页 :

http://java.sun.com/security/signExample12/



: 以上的例子为简单起见 , 使用了 keytool 产生的自签名证书 . 其实 , 用户也可以

使用 keytool -certreq 向商业 CA 中心申请电子证书 .



: 若通过 ObjectOutputStream 向一个文件中多次以追加方式写入 object, 为什么用 ObjectInputStream 读取这些 object 时会产生 StreamCorruptedException?

:
使用缺省的 serializetion 的实现时 , 一个 ObjectOutputStream 的构造和一个 ObjectInputStream 的构造必须一一对应 .ObjectOutputStream 的构造函数会向输出流中写入一个标识头 , ObjectInputStream 会首先读入这个标识头 . 因此 , 多次以追加方式向一个文件中写入 object , 该文件将会包含多个标识头 . 所以用 ObjectInputStream deserialize 这个 ObjectOutputStream , 将产生 StreamCorruptedException. 一种解决方法是可以构造一个 ObjectOutputStream 的子类 , 并覆盖 writeStreamHeader() 方法 . 被覆盖后的 writeStreamHeader() 方法应判断是否为首次向文件中写入 object, ? 则调用 super.writeStreamHeader(); 若否 , 即以追加方式写入 object , 则应调用 ObjectOutputStream.reset() 方法 .


: 对象的序列化 (serialization) 类是面向流的 , 应如何将对象写入到随机存取文件中 ?

:
目前 , 没有直接的方法可以将对象写入到随机存取文件中 .
但是可以使用 ByteArray 输入 / 输出流作为中介 , 来向随机存取文件中写入或从随机存取文件中读出字节 , 并且可以利用字节流来创建对象输入 / 输出流 , 以用于读写对象 . 需要注意的是在字节流中要包含一个完整的对象 , 否则读写对象时将发生错误 . 例如 ,java.io.ByteArrayOutputStream 可用于获取 ObjectOutputStream 的字节流 , 从中可得到 byte 数组并可将之写入到随机存取文件中 . 相反 , 我们可以从随机存取文件中读出字节数组 , 利用它可构造 ByteArrayInputStream, 进而构造出 ObjectInputStream, 以读取对象 .


: 运行 RMI 应用时 , 可不可以不手工启动名字服务 rmiregistry, 而是从程序中启动之 ?

:
可以 . java.rmi 包中提供了类 java.rmi.registry.LocateRegistry, 用于获取名字服务或创建名字服务 . 调用 LocateRegistry.createRegistry(int port) 方法可以在某一特定端口创建名字服务 , 从而用户无需再手工启动 rmiregistry. 此外 ,LocateRegistry.getRegistry(String host,int port) 方法可用于获取名字服务 .


: 使用类 PrintJob 进行打印操作时 , 应如何设置打印机名等打印属性 ?

:
使用如下方法可以获得 PrintJob 的实例用于控制打印操作 :


Toolkit.getPrintJob(Frame f, String jobtitle, Properties prop)

那么对于打印属性的设置可以通过对 prop 的属性设置来实现 , 打印属性包括 :

awt.print.destination:
可以是 "printer" "file"

awt.print.printer:
打印机名

awt.print.fileName:
打印文件名

awt.print.numCopies:
打印份数

awt.print.options:
打印命令的打印选项

awt.print.orientation:
打印方向 , 可以是 "portrait" "landscape"

awt.print.paperSize:
纸张大小 , 可以是 "letter","legal","executive" "a4"




: JDK1.1 Thread 类定义了 suspend() resume() 方法 , 但是在 JDK1.2 中已经过时 , 应使用什么方法来替代之 ?

:
Thread.suspend
本身易于产生死锁 . 如果一个目标线程对某一关键系统资源进行了加锁操作 , 然后该线程被 suspend, 那么除非该线程被 resume, 否则其它线程都将无法访问该系统资源 . 如果另外一个线程将调用 resume, 使该线程继续运行 , 而在此之前 , 它也需要访问这一系统资源 , 则将产生死锁 .

因此 , Java 2 , 比较流行的方式是定义线程的状态变量 , 并使目标线程轮询该状态变量 , 当状态为悬挂状态时 , 可以使用 wait() 方法使之处于等待状态 . 一旦需要该线程继续运行 , 其它线程会调用 notify() 方法来通知它 .



: 使用 JDBC 编程 , 应如何控制结果集 ResultSet 的指针 , 使之能够上下移动 , 以及移动到结果集的第一行和最后一行 ?

:
JDK1.1 ,ResultSet 类中只定义了 next() 方法支持数据指针的下移 . 但在 Java 2 ,ResultSet 类增加了如下方法支持数据指针的移动 , 包括 :


ResultSet.first():
将数据指针移到结果集的第一行

ResultSet.last():
将数据指针移到结果集的最后一行

ResultSet.previous():
将数据指针上移一行


以上的方法定义在 JDBC2.0 的规范中 , 所有支持 JDBC 2.0 JDBC 驱动程序都可以支持上述方法 . 目前 Intersolv OpenLink JDBC 驱动程序厂商均有产品支持 JDBC 2.0 .


: 哪几种 Web Server 支持 Servlet? 如何使 IIS 支持 Servlet?

:
目前 , 支持 Servlet 的服务器端产品主要有 : Sun 公司的 Java WebServer,Lotus DominoGo WebServer,BEA weblogic Tengah Server,Jigsaw,NetForge,AcmeServer Mot Bays Jetty .

此外 , 一些第三方厂商也开发了 Servlet engine, 以使其它 WebServer( Netscape Web Server,IIS ) 能够运行 Servlet, LiveSoftware Jrun(http://www.livesoftware.com/ products/jrun/) .


: 如何在 Java 应用中将图像存储到图像文件中 ?

:
Java Advanced Imaging API(
包含在 Java Media API ) 允许在 Java 应用中执行复杂的 , 高性能的图像处理 .JAI API 提供了存储图像的能力 . 目前 ,JAI API 支持以下几种图像文件格式 :BMP,JEPG,PNG,PNM,TIFF. 下面给出了将图像存储到 BMP 文件的一段代码 :


OutputStream os = new FileOutputStream(fileToWriteTo);

BMPEncodeParam param = new BMPEncodeParam();

ImageEncoder enc = ImageCodec.createImageEncoder("BMP", os, param);

enc.encode(img);

os.close();

有关存储图像文件的编程指南请参考以下网页 :

http://java.sun.com/products/java-media/jai/forDevelopers/jai-guide/



: 如何用 Java 语言向串口读写数据 ? font>

:
Sun
公司的 Java Communication API2.0 可用于读写串口 , 它支持 RS232 串口和 IEEE 1284 并口 , 提供了一种与平台无关的串 / 并口通信机制 .

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=526712

你可能感兴趣的:(Java常见问题集锦)