数学建模社区-数学中国

标题: [转帖]Java常见问题集锦(来自Sun中国官方站) [打印本页]

作者: god    时间: 2005-3-31 01:31
标题: [转帖]Java常见问题集锦(来自Sun中国官方站)
问: 如何设置Java 2(JDK1.2)的环境变量?  / a& b- }: a- ]

, Z+ U: Y1 _* v0 Y2 j答: Java 2安装后,需要设置PATH和JAVA_HOME环境变量.与JDK1.1不同的是:设置好JAVA_HOME环境变量后,JVM将自动搜索系统类库以及用户的当前路径.  0 U! j. e3 `, T, P& o/ c8 Y
Java 2环境变量的设置如下例所示:  ) B* p' d; I( l1 J4 h
Solaris平台: setenv JAVA_HOME Java2的安装路径  
( s0 _( H0 e8 ^& @( S! Gsetenv PATH $JAVA_HOME/bin{PATH}  & H- ]6 K5 j, ^; g) B
Windows平台: set JAVA_HOME=Java2的安装路径  + U: \9 p, p4 `" s% D4 v- v; z  O
set PATH=$JAVA_HOMEbin;%PATH%  : M5 `) M2 E5 k0 E6 s% I6 }

3 f& l; d- N1 m' ?问: 哪些Java集成开发工具支持Java 2?  
6 X) ?. o5 \* [7 q5 A. t  X7 g) r& m
# G5 i5 \6 U  y7 ^  V/ d$ n答: 目前流行的Java集成开发环境,如Inprise的JBuilder,Symantec的Visual Cafe, Sybase的PowerJ,都支持Java 2.  
# C5 l, X; T& }, z1 y3 i6 E' E0 B! B9 j( I: b' N
问: 如果在Netscape或IE浏览器中运行Java applet时出现了错误,如何确定错误范围?  
4 G& ^3 z9 }/ Z& @5 H6 ]6 Q% J& q; ~, R7 X" X0 a
答: 当java applet在浏览器中运行时,使用的是浏览器本身的缺省JVM.而不同浏览器对JDK的支持程度也不尽相同. 因此,在Netscape或IE浏览器中运行Java applet出现了错误,建议使用JDK提供的工具appletviewer或Sun公司的Hotjava浏览器来测试该applet,以确定错误的产生是与浏览器相关.  # ]9 R3 |( B. a! y9 Q# y
    如果applet在appletviewer或Hotjava中运行一切正常,则错误的产生是由于浏览 器不完全兼容JDK而引起的. 此时,解决方法可以是使用Hotjava浏览器或者安装 Sun公司的Java Plugin.  
+ u& V- c" b* f* {    如果applet在Hotjava浏览器或appletviewer中运行即发生错误,则应当根据错误 提示检查applet程序.  
% J" l+ C5 i1 u9 I" U" O& s0 ~
0 C7 L: U1 |+ e1 F2 V& ]$ L问: 当用JDBC向数据库中插入数据或从数据库中提取数据时,为何有时中文字符会显示为乱码?  1 ^* s) n* }) n6 P) K

: q5 |% F6 a5 L/ @+ s) \+ U答: 这个问题的实现通常与各个JDBC driver的实现有关. 目前大多数JDBC driver采用本地编码格式来传输中文字符,例如中文字符"0x4175"会被转成"0x41"和"0x75"进行传输. 因此我们需要对JDBC driver返回的字符以及要发给JDBC driver的字符进行转换.  ' Q. j! ~, M* h+ ~* @
1 s% R/ r# `# p
当用JDBC driver向数据库中插入数据时,需要先将Unicode转成native code; 当 JDBC driver从数据库中查询数据时,则需要将native code转换成Unicode. 下面给出了这两种转换的实现:  # U; p: P- J! y# W! x" }

2 l* V7 C6 m5 z# X% r
% l( v% @! z7 X* M+ m  \* ^String native2Unicode(String s) {  
: w( |; s$ v3 @& R4 }/ H1 M4 U6 r% u
if (s == null || s.length() == 0) {  
% y3 k3 s$ a/ X% Q3 d
8 ?  r$ H) w  F' J2 w% ?% G( T9 Dreturn null;  8 ?! j- a7 y2 A1 A
5 q0 S, T' J  B& l/ N, K4 a$ E
}  
3 z3 y8 V3 A) n% i, X+ X6 V+ [; o) G9 I  C; J  P5 `
byte[] buffer = new byte[s.length()];  
2 ]- S# E+ ~7 ?4 g1 j0 @& _, ~
% [/ q3 n* |* D$ M5 mfor (int i = 0; i s.length(); i++) { if (s.charAt(i)>= 0x100) {  # n  L7 g! ?. M7 `, N6 n4 i

& d/ m4 u+ M/ Jc = s.charAt(i);  + \/ b# N, [6 b
9 L# D, G, H) \; l! O* J
byte []buf = (""+c).getBytes();  $ s0 ]7 U) p! B; r
5 E( i& `0 j) E
buffer[j++] = (char)buf[0];  
6 u% i+ X/ ?3 K6 r( x
7 `. g# \9 ]1 m2 T# \9 ^; pbuffer[j++] = (char)buf[1];  7 O( u  O6 W: N! x5 z: j
( w) B5 r! U0 D4 |- L+ s
}  
2 F, ?- m; u: B/ d* V" X9 @2 e
- f4 l3 a$ w! lelse {  
. {8 x; H( B! Z5 F8 e8 v4 G
' U1 _3 p; f: b0 G3 B7 t5 rbuffer[j++] = s.charAt(i);  - A5 H4 C6 [! S" r/ [3 q, W
$ C) W& x5 `5 x, g4 ^) Q
}  
! N$ Z# j* x: e2 X3 @8 M/ ~* a; S
8 ?; J8 Z6 h; B( w7 q}  
5 A/ S2 J3 t$ v, C* W8 i+ Z+ [- G" d1 h- b# m" G
return new String(buffer, 0, j);  / B# R2 `' K; P% W- I# Z3 |' V
* Y! H$ }2 \/ `( t
}  ' L/ J) |" [$ M- F( Y
; g( O. [$ ?8 ]" p- b
除使用以上两个方法之外,有些JDBC driver如果对jdbc driver Manager设置了正确 的字符集属性,以上2个方法就不需要了.  
) ?, N$ M& w# f! {( W2 W
4 `- S6 h. q- Q0 `: f' @" V; J2 v8 e% i2 Z. d+ n! }4 J( P
问:  
, b' v+ P3 L3 P1 R4 m" W1 L9 E& j# b9 p1 T当用Servlet来处理http请求并产生返回的HTML页面时,如何使HTML页面中的中文字符能够正常显示?  
) e! M2 F9 ~3 E6 ]. c  }+ m/ U$ M6 k7 l
答:  
, H1 X$ ?. W$ C. I7 k: o  wjavax.servlet.http.HttpResponse类用于产生返回页面.通过HttpResponse定义的方法getOutputStream()可以获得ServletOutputStream的实例,这样用户就可以利用ServletOutputStream.write方法向输出流中写入返回页面的内容. 但是ServletOutputStream使用的是缺省的编码方式,如果要使返回页面中的中文字 符能够正常显示,最好显示地指定所用的字符编码方式. 通常需要构造一个 OutputStreamWriter , 例程如下:  . ?' n0 g4 D; m+ w

; @& ?" x% Y7 M# n2 |  o8 \* w0 s' \+ T
public void doGet (HttpServletRequest req, HttpServletResponse res)  
  M# S1 ~6 v, j4 t0 c; a2 b* c5 [+ m- |7 D
throws ServletException, IOException  / [! |& d! G+ i! b+ K6 A( o8 Y- k
# x- e7 D  Z# y0 v( \  j+ Z; l) u0 k( l
{  - ?+ n+ s! }" D
# w2 w9 v& I; l9 e
res.setContentType("text/html");  
% [; `1 k/ b; B) _3 P
! p: i: w* b0 f! \7 xServletOutputStream out = res.getOutputStream();  
. A& ^' y3 j; b1 _( s7 \6 C' a% R0 m! h
OutputStreamWriter ow = new OutputStreamWriter(out,"GB2312");  
- Z7 L, `( b& {1 U/ q3 h
! K9 E# c; n% g7 I2 @0 O: Cow.write("这是测试");  1 k* |# Y, O( Z8 R9 D( F" ^
9 O6 s- u: z* n" z+ N* t* z, P& |
ow.flush();  
3 i8 Q' A- S4 o- l+ Q+ t4 \
3 i$ H9 }) d6 D/ B- kow.close();  0 `' L/ ~9 ]* p  @/ O1 N9 {
& [* X: r4 }; ~, e, ?& C0 g
}  
0 h6 L) U" Z& ^' Y$ z/ M7 b
6 u) w3 G% f0 q# f
6 G) T' L2 M- C5 N问:  $ [0 {* {" l: W8 h) L
如何设置Java WebServer的CLASSPATH,以包含用户的class文件?  
4 `5 M6 w+ |( a" q4 A4 f- S% C
& A: {# ~  @" ]) h. i& F3 P答:  
* l, `9 r' L- Y- R# {$ @) K  ?有两种方法可以设置Java WebServer的CLASSPATH环境变量,以使用户编写的Servlet能够调用用户的class文件.  
. t5 b- F! d8 k9 b0 a将用户的class文件放到 JavaWebServer_Dir/classes目录下,在Java WebServer 启动时,classes目录被自动加入到CLASSPATH环境变量中了.  
5 L, b: L2 W* d* {; _: g# d修改httpd.nojre文件,将用户class文件所在的路径名加到CLASSPATH环境变量中.  
& i; Q- N7 `; |+ P1 c; }! f( y/ F( f

) J! I8 F/ A* H问:  
8 d+ Q2 ~2 `4 `- n$ _# @  _为什么在Windows平台上用Naming.lookup来获取远程RMI对象时会很慢?  ' x9 M( c0 B) b# V% C+ K

0 p% Q( q. T; \6 O! @. H. i5 p& ]答:  
/ z" h8 g' R) @! O9 m机器的网络设置不正确很可能会引起该问题的发生.  
+ [! l! g3 i! a5 E; y% P/ ]9 E+ \RMI使用了Java网络类,特别是java.net.InetAddress类,它将查询TCP/IP的主机名, 包括IP地址到主机名的映射和主机名到IP地址的映射.在Windows平台,这种查询功能 是由本地的Windows Socket库来实现的. 因此延时是发生在Windows库中,而非RMI中.  
, c! n. p: J9 v% H: ?; z$ Z9 X: ]3 P  u5 V6 T
如果你的机器设置成使用DNS,问题通常是DNS服务器查不到主机名,你所发现的延时 是DNS查询的延时. 请尝试将RMI通信中涉及到的所有主机名/IP地址加到本地文件 winntsystem32driversetchosts或windowshosts中. 格式如下:  7 `3 Z) h. F% ?# D- V+ ^/ y
" R( I& ]/ z: M# J5 `6 M( w0 @
IP地址 主机名  / h: `$ P$ h+ v8 _7 T6 b/ L
7 d3 i$ l! X9 H" {3 A
如此设置应当可以明显地减少查询所花的时间.    _3 x' v1 C& _% a3 |. T* B- k

* W& r% Z2 U5 K0 Y问: 编写Java application时,如何设置proxy的信息,以便访问外部网站?  
& U. F" q! E" u6 a9 r
' J. Y: t7 [; z. ]5 v4 q) t4 l: w答:  
9 v- N4 D8 f- |若在java application中访问外部网站,首先应设置proxy信息,样例代码如下:  0 z; B4 x. o  ?* i& m' V
; L8 D3 |+ X7 J5 K5 D+ T! R

' L8 E6 X9 L/ V  [$ _3 k; b8 {import java.util.properties;  5 }  H% z6 D0 u4 `. L$ y

+ v0 y: t9 A% L- ?) n) ^6 A& X.....  ! X( N; A6 W8 _$ n3 z$ [

) j9 j2 a' ^- mProperties sys = System.getProperties();  
- F! I( I) O6 f# l
% J' b3 A' T3 d! _" S0 D) ^/ x, Gsys.put("proxySet","true");  . j4 L; J) b/ ?/ H  z6 w! d  k3 [

6 n6 ^# j0 O' @, usys.put("proxyHost","myHTTP.proxyserver.com");  / k; ?6 c9 W4 K. _4 S
0 y  R9 Z" j/ R8 F2 V1 K
sys.put("proxyPort","80");  3 u) h# g& z( F) G, z

# o- m% J; w5 w; q: ?- h% D4 SSystem.setProperties(sys);  3 B- F$ ?5 J9 U& T  e9 s* _  c& D1 u

! ~8 b0 a# V1 t1 t4 Y/ F' M3 y) ?" G# m

" F$ B3 `" a% @. P; Bu = new URL(website);  
7 {) ?; l  _' O0 q+ w4 k  ]
( l8 e2 S- k5 U0 Uconnect = (HttpURLConnection)u.openConnection();  
  l4 o8 i0 S2 [/ \% v+ N# G9 e8 E% ~3 H2 j( i
.....  ( H# N/ ]/ W7 F2 f$ `$ Q
; R- N! `9 G& Y( Q; o# H, z
问: Swing组件JList的列表数据修改了,如何通知JList改变显示?  - {: D5 ]; Y8 g8 o& `
, V, c# i7 J3 M6 B( F. F' U/ n" Z
答:  * W% L$ B$ Z" l: w2 S. U
JList组件有一个单独的显示模式ListModel来表示JList的显示数据.  / a5 r( y2 `9 S6 I
JList创建以后,JList数据元素的值及数据元素的数量可以动态地改变.  & K1 F8 \, ~+ `. K4 T% T! r/ Q
JList在它的数据模式ListModel中观察数据的改变.因此,一个ListModel 的正确实现应当在每次数据发生改变时,通知事件的监听者.  
9 ]! _0 V+ y. E1 P当使用构造函数JList(Object[])创建一个JList的实例时,系统将自动 创建一个DefaultListModel的实例来存储JList的显示数据, 可以调用 DefaultListModel中定义的简便方法来动态地修改JList的数据,如 removeElementAt(index),addElement(Object)等. DefaultListModel 在修改数据的同时,将通知JList关于数据的改变.  + J; y% m2 [  |& B

; s- J/ n* A2 G% @) y$ _& F问:  
1 `6 n* X' Q' k& V6 O- o在Java applet中如何实现一个模式对话框?  
9 ], [- Q! f- A6 m! c& d' r+ ?2 [$ o* }  i3 W4 o8 V
答:  
/ ^* D( {- I& [. F6 _- ?" A& V在Java applet中实现模式对话框的关键就是在创建一个对话框的时候 要为该对话框指定一个正确的父窗口.因为Applet是Panel类的子类,不 可以作为对话框的父窗口,所以首先要获得applet所在的窗口,作为模式 对话框的父窗口. 样例代码如下:  * V* O$ B; p9 f4 l
: S) D# ?4 m2 [0 G8 H9 \

6 K4 R" i. a2 h% U3 }' r.....  ) x1 |& G# i) M4 c
6 u7 g6 J3 q- D' L# k
Dialog d = new Dialog( getParentWindow(comp),title);  ' E: ?$ [2 N  D
7 m5 u+ u8 O% K* z  y
// comp为applet上的任意一个组件  # P) x1 u5 l6 u# o

( j0 u; [; x+ H0 L$ a* [....  6 s9 Q* m4 x5 Z6 ~3 a' g
/ G9 e3 f  Q# o& w" a
+ }1 V  G& e3 R2 i+ M7 B
1 e$ ~$ D2 _" M% n
public void getParentWindow(Component compOnApplet,String title){  
% l; K% ^% S$ v* z
, F4 T- |! Z! s  L4 [8 ZContainer c = compOnApplet.getParent();  
9 e. u# Q; L; E( q, l
) V9 ^+ `+ y' rwhile (c != null) {  3 X, f, h- Q  Z0 `4 _: S5 T. _
) U8 m0 Y/ f/ e! z5 W4 K# F# p
if (c instanceof Frame)  
) ?9 D' A$ v  y& k- D7 y5 k7 v: M) k) A' q/ W, C
return (Frame) c;  
6 I) L6 }/ {- v6 U7 k- l  {, z$ F8 f; w6 s; a1 x1 d) L
c = c.getParent();  : k! j5 p7 C* g& W

9 z  V$ x$ W2 G! B}  
( m5 t$ l$ J7 n. e0 W9 x  A3 n2 B7 I
return null;  
! l! w' n! r+ Y4 c* C# n5 B
8 y0 M8 D! r; E6 k8 ~9 o6 ]}  
* |0 c7 w& }+ I# ?5 Y6 N/ X8 q
) A% }% A/ `+ U* e" |* _问: 在Java applet中如何显示另外一个HTML页面?  7 g* C& n$ P+ M+ o- n9 q' z

3 M  u' `5 d' H, o/ N+ ^6 y答:  
, i& y( ^; M5 M, I' ^/ Z通过java.applet.Applet.getAppletContext()方法可以获得与该applet相关的AppletContext, AppletContext.showDocument(URL)方法就可以使applet所在的浏览器显示另外一个网页.  
+ Z9 S0 h2 @9 W3 |) v' v8 h5 t
( d4 [! H  W3 C/ L% g. \% O( F问:  / S# s) [  b) {4 G3 J
用JDK实现的签名applet,可否在Netscape或IE中运行?  : r& n# z+ `" g/ t% E3 f

( B) R; ]5 Z9 R7 l* e, U9 `" J9 \! C* S" y答:  9 B- N# _1 g8 ?/ o( z
用JDK实现的签名applet,不可以在Netscape或IE中运行,但是可以在Hotjava浏览器中运行.  
- s# ]( O0 t/ O& }6 w8 f2 d1 t/ n$ B4 Y
不同的浏览器提供了不同的签名applet机制,如Netscape提供了zigbert工具和 Capability API, 而IE则需要使用CAB文件. 但是,无论是Netscape工具产生的 签名applet,还是用IE产生的签名applet,都不可以在其它的浏览器中运行.  
& P: V. }& ~0 W- D8 K2 u! t6 @3 }( |
如果要使JDK产生的签名applet能够在Netscape或IE中运行,解决方法是在 Netscape或IE中安装Java Plugin,则用JDK实现的签名applet就可以在这两种 浏览器中运行.  
' i( ^. C; k* b2 I2 R4 K
7 o3 {# ?! N: B* y% Y问:  
6 Q! [! h7 N6 X4 w用JNI技术可以从Java应用中调用C程序库,但是如何使该C程序库可以调用另外的C程序库?  
, R( }1 M. I( ^8 F5 U- S$ A/ ~1 {" w0 Q& P- |8 w5 h' }
答:  % L& z- G4 |" W
如果一个被Java调用的C程序库C1仍需要调用另外一个C程序库C2,那么在编译C1的时候应当联接程序库C2,步骤如下(Solaris平台):  $ L6 }, U5 c  W! a  p
编写调用C库的Java文件,并编译.  1 l+ w, g8 P8 d7 W. V( K; s7 j
javac java文件名  
& a7 _* ]/ f: c7 M/ J3 Y" T9 Y' U: r0 [& U# D

  r$ W$ K( P7 y3 D产生C程序头文件  / l! b5 z0 h* t+ [
javah -jni java文件名(不带后缀.java)  # f6 H- L+ ^  s* o+ Q

0 K/ E/ W! O! J5 r& W' ?  ]' A" _2 e7 I  F& A9 E6 F
编写被Java调用的C程序C1.c,以及被C1调用的C2.c,并编译.  / c$ p$ B1 \8 t; m  `/ K
cc -G -Iinclude路径名 C2.c -o libC2.so  1 L* p) y  Q- V6 K* l
cc -G -Iinclude路径名 -lC2 C1.c -o libC1.so  # e/ `  K4 d$ p
" D9 \$ @" \  W1 T& B8 c- @

/ b, r9 \5 W% L2 M设置环境变量  ) H' U6 C# C& f% _8 @
setenv LD_LIBRARY_PATH libC1.so,libC2.so所在路径  % a8 q& X, k6 R# \# D  {
{LD_LIBRARY_PATH}  
% n, Z8 @1 u+ q
2 ^5 p9 Y2 K7 \0 c. V9 v! R
4 |/ B7 V( J5 O- j5 X运行java应用  
# k  n% O( h4 k, z0 D
+ k/ ?; o3 {+ e; `
: Q! ]1 _& H4 C9 K0 L3 i9 g问:  
- t* K1 @  @$ k' Y在Java语言中,如何列出PC机文件系统中的所有驱动器名?  
! j2 R! R+ r, R' k# C9 H' n1 g" t( @' Z" \
答:  
6 \2 a6 W! y8 P' W, p在Java 2版本中,java.io包中的File类新增加了方法listRoots()可以实现这一功能.  - Z$ B4 }: |. U
8 U& @  P, S& O9 V2 X( w  q9 F
问:  0 H! K0 {+ N/ }4 q" C
为什么Runtime.exec("ls")没有任何输出?  
4 O1 u0 P' @6 A2 f+ T( Q8 k! F8 _- V$ P1 @* n, K9 a, i! E
答:  
) {0 k& ~5 g3 O4 R& J调用Runtime.exec方法将产生一个本地的进程,并返回一个Process子类的实例,该实例可用于控制进程或取得进程的相关信息. 由于调用Runtime.exec方法所创建的子进程没有自己的终端或控制台,因此该子进程的标准IO(如stdin,stdou,stderr)都通过Process.getOutputStream(),Process.getInputStream(), Process.getErrorStream()方法重定向给它的父进程了.用户需要用这些stream来向 子进程输入数据或获取子进程的输出. 所以正确执行Runtime.exec("ls")的例程如下:  ; \, ?( \/ v8 C# e
% ^7 T1 J; j- q9 P1 ~) C
+ P) X, F6 t+ ~8 `# N5 l# r
try  ' Y# b5 z, M8 Y3 g9 ~) H9 Y
, a! |5 q8 B- L, Y7 ~& l8 o
{  4 v* L8 ], B! r
% V& d- \) b! S' _) t* c' M1 p0 E
process = Runtime.getRuntime().exec (command);  " z6 y8 H7 @' X2 Y9 h3 P

5 ^5 J) j0 z2 b% CInputStreamReader ir=newInputStreamReader(process.getInputStream());  / b$ c- R) v4 {. ^( l* U

$ Y3 l* X  k( VLineNumberReader input = new LineNumberReader (ir);  
; a$ ~. n5 F$ V% N" c8 Z6 K% _* @* ?5 G" Y- K7 }
String line;  
" ?5 I% p$ l! r/ n, U$ e- p0 S! J$ W; W# c: a. y! b* t/ L
while ((line = input.readLine ()) != null)  0 Y4 f: v1 S# ^7 O" |2 @
- w) C3 Y3 c9 W2 n
System.out.println(line);  
* \- a: `* f' p2 F3 ?0 G. W1 l& \5 S2 u' M  r% O
}  ' w' I7 W4 S* l7 p5 X

) f$ o' s+ K# o3 g" Pcatch (java.io.IOException e){  ) i# S/ g: ^) G* t! v5 f6 C

+ L6 l: U* r1 CSystem.err.println ("IOException " + e.getMessage());  / L3 M+ ]* k3 W

) P$ Z9 M# J# e# l9 O) {' u6 }}  
/ _$ Z+ m, w6 f- {2 x' \$ y7 r* q: w3 o  d7 r0 g
4 f+ ?( t! [. I( R* M0 @
问:  / ^  I; u! ]! D- r7 h: ?3 `% M
如何产生签名applet,以使applet能够访问本地资源?  
. m9 O& g" z! U( b3 l6 |) t5 ^! {1 v) u3 k$ K; k; S
答:  7 x' J" ~, }" h* _% ]2 z, p1 c
在jdk1.1中,可以使用javakey命令来产生公钥,私钥,证书和签名的jar文件,详细资料 请参考: http://java.sun.com/security/usingJavakey.html而java 2对签名机制做了比较大的改进,允许用户更灵活地设置安全权限.Java 2提供了三个工具:keytool,policytool和jarsigner来实现签名applet.例如,Joe编写了一个签名applet:SignedApplet.java,那么产生一个简单的签名applet的过程如下:  % p* V3 R7 u7 Z
6 j- r8 ]% S9 Z7 s; I
6 J; b* J; z6 o8 ?4 g
//产生密钥,密钥别名为joe,口令为sign12,存放在密钥库joestore中  4 ^1 a* t8 ]9 K: ^! {* w! P

& j# G6 e* S, J3 H: M" E9 O; lkeytool -genkey -alias joe -keypass sign12 -keystore joestore  6 J9 c) T" x& f" j& l

" }" {& g/ F! x; w, X+ O- o2 g//将SignedApplet.class及相关文件打包成jar文件  
" a7 U9 F8 a' G$ E; G, o; v  u; Y' r' S/ T8 R1 Y1 N$ _  t
jar cvf SignedAppletDemo.jar  . V2 O" ^* _4 Z0 U* [' y( D
# [# J& `0 L. X9 @8 T& M: d3 Z  ?
//利用keytool生成的自签名的证书产生签名applet(jar文件)  
% F- L, b% j3 e7 A( z* K" p+ b' I7 s5 b
jarsigner -keystore joestore -signedjar joe.jar SignedAppletDemo.jar joe  ; n8 _6 i& F% m% W, X+ X

# [( x! N/ b9 n//将自签名证书从keystore中输出到文件  
% p6 o  z5 n: a; G; r$ h- P- f2 P/ |! B) W
keytool -export -keystore joestore -alias joe -file joe.cer  9 ~2 V2 T  A4 C9 @. A

1 x& u! f: s8 h9 ]( Z. T" l0 @* x* N% B6 E# z/ x/ c
  \. T0 V6 }0 @, ^" C# p9 s
而对于签名applet的接受方Susan,需要通过如下步骤来安全地执行  1 k' @6 o/ o' O) q
" ?3 U4 S/ B7 A5 E1 v; X% j
Joe编写的签名applet:  ' P6 d4 k* q- l1 K( U) d

+ e, }7 [6 b0 O/ m' `//得到Joe的证书并将之读入到密钥库中susanstore中  ( j' V6 x7 Y1 K" h) h+ O

+ H- n% E% `2 \3 s7 q! k- Vkeytool -import -alias joe -file joe.cer -keystore susanstore  ' o" Q' b% ]; Y' O  ^: H
) f% c6 S1 w" t( \+ `+ l) R
//运行policytool产生满足Susan要求的policy文件  & f- U' M3 \# x7 I
2 r2 C: r# |( S# P0 s; ?" H# C
policytool  , a  f3 p1 d- k9 ]

, e/ W. g/ B7 x//用appletviewer运行之,或在浏览器中安装java plugin来运行之.  * K; l3 F. Q& E( N
; H) }% I7 @  h! h8 v1 P

, q' l6 J$ F9 Q. z$ }6 U& H0 d4 \% u5 M
关于签名applet在Java Plugin中的部署请参考以下网页:  
# ]1 Z/ j; j; k. w) j3 ^9 I
3 n8 j4 g5 T9 j/ P' l  c& phttp://java.sun.com/security/signExample12/  , Y+ M  ?, i' k
- k, |1 E2 F6 q' U. K; M8 Q
9 o+ |* ~9 t4 x$ _  `" X
/ O' M1 U! K& o- {' \% L: ]  H
注:以上的例子为简单起见,使用了keytool产生的自签名证书.其实,用户也可以  
; K/ l+ K' A9 O' r$ s
& l1 U+ s- d/ ^8 \" c! `  l! @9 {使用keytool -certreq向商业CA中心申请电子证书.  " y1 c, V7 j" ~. T% v. U3 G
% X; \# r* e/ K
6 C1 J# C. Z$ ^9 }& J) k
4 w8 L& ]3 Q, Y2 z/ ?

. I. ]+ M! Y& X) X0 u" q% S问:  ( d  T8 k. h+ h( A
若通过ObjectOutputStream向一个文件中多次以追加方式写入object,为什么用ObjectInputStream读取这些object时会产生StreamCorruptedException?  
: W" X! ?! X+ M) |7 L* J" j4 Q& J/ Z/ u: e: z6 Z- s5 D
答:  ' l& i2 O$ i0 i$ d" r
使用缺省的serializetion的实现时,一个ObjectOutputStream的构造和一个ObjectInputStream的构造必须一一对应.ObjectOutputStream的构造函数会向输出流中写入一个标识头,而ObjectInputStream会首先读入这个标识头.因此,多次以追加方式向一个文件中写入object时,该文件将会包含多个标识头.所以用ObjectInputStream来deserialize这个ObjectOutputStream时,将产生StreamCorruptedException.一种解决方法是可以构造一个ObjectOutputStream的子类,并覆盖writeStreamHeader()方法.被覆盖后的writeStreamHeader()方法应判断是否为首次向文件中写入object,羰?则调用super.writeStreamHeader();若否,即以追加方式写入object时,则应调用ObjectOutputStream.reset()方法.  
$ s: S2 P' n6 [  K) H
1 b' r. d# @5 A2 f) X( L问:  
) w5 D7 e! ^  g: f对象的序列化(serialization)类是面向流的,应如何将对象写入到随机存取文件中?  $ M) v; J" k6 s- J

1 D& G5 n# C- C8 }答:  
- R+ a5 d* e' ?$ }目前,没有直接的方法可以将对象写入到随机存取文件中.  % o* q% j5 W8 g; y
但是可以使用ByteArray输入/输出流作为中介,来向随机存取文件中写入或从随机存取文件中读出字节,并且可以利用字节流来创建对象输入/输出流,以用于读写对象.需要注意的是在字节流中要包含一个完整的对象,否则读写对象时将发生错误. 例如,java.io.ByteArrayOutputStream可用于获取ObjectOutputStream的字节流,从中可得到byte数组并可将之写入到随机存取文件中.相反,我们可以从随机存取文件中读出字节数组,利用它可构造ByteArrayInputStream,进而构造出ObjectInputStream,以读取对象.  
+ w1 [5 X4 _9 q$ g& f: J9 t
  j" @/ n6 B# K- b问:  ) g8 c/ `' A+ U+ C, @! Z5 @, j) G
运行RMI应用时,可不可以不手工启动名字服务rmiregistry,而是从程序中启动之?  % s# Y+ P) G3 d1 L- s; |
3 q' [( O2 S7 S  e
答:  
. A- U: b2 k" T9 E1 D可以. java.rmi包中提供了类java.rmi.registry.LocateRegistry,用于获取名字服务或创建名字服务.调用LocateRegistry.createRegistry(int port)方法可以在某一特定端口创建名字服务,从而用户无需再手工启动rmiregistry.此外,LocateRegistry.getRegistry(String host,int port)方法可用于获取名字服务.  
+ j6 S# A6 J& R& ^. u! l$ Q- y, Z9 D4 @: S& L% b$ L
问:  
/ L  R8 M' y7 E& h  j& Q( d: k使用类PrintJob进行打印操作时,应如何设置打印机名等打印属性?  2 H& f- r. I, Y) }$ i. }% I
. {6 U7 F9 P) S1 I7 V; l
答:  / ?4 g& I. a/ z/ A% e$ p
使用如下方法可以获得PrintJob的实例用于控制打印操作:  0 m# j4 y8 G3 h4 d% R( D% J
- _( M/ `0 q6 z/ ?* m
, f' k; [" O, j+ f% K# w$ a6 ^
Toolkit.getPrintJob(Frame f, String jobtitle, Properties prop)  
8 I6 j% i$ s  f* M& P* b
2 L1 J) J0 @- ?4 i* H那么对于打印属性的设置可以通过对prop的属性设置来实现,打印属性包括:  0 P( N+ m; G0 V8 F4 x  @

% C& {* D% b. Pawt.print.destination: 可以是"printer"或"file"  9 A8 M4 s$ f# p# W1 h* i- f  Q

. P& r# x$ E; k* ]" Q+ R) nawt.print.printer: 打印机名  6 B0 p/ {. z& n& p; }
$ F3 O- v2 F) I+ g) r& _0 c5 v6 l
awt.print.fileName: 打印文件名  , [5 l# m( a  g

3 W; L8 }4 D7 ^  I( Sawt.print.numCopies: 打印份数  
* R( a/ S5 |( _& ~/ X7 V
. s  ?( r( u, U; Cawt.print.options: 打印命令的打印选项  + N# E$ f3 j4 e' V

/ K/ m- B! t9 L' \4 O9 ]& g! |$ cawt.print.orientation: 打印方向,可以是"portrait"或"landscape"  
4 x: a) I" h3 {  p
  p; {$ k( n1 Q& U" I8 [awt.print.paperSize: 纸张大小,可以是"letter","legal","executive"或"a4"  
) \2 X: ^  m3 d, R4 d
1 v' Q, _/ E, E- e' Q0 }+ o
) }2 H8 ?$ d) J6 l  O5 w* n
) j0 \, n6 W' x0 h# w8 u! D" o& J" B$ X! @7 f: M* m- o

# y6 Y7 t; @/ f; M  `1 O5 ]' L) E+ F& I: R; d$ b4 S
问:  
$ n- R8 w  t7 i; s$ E# Z在JDK1.1中Thread类定义了suspend()和resume()方法,但是在JDK1.2中已经过时,应使用什么方法来替代之?  2 v* h6 d# ]5 U; h" H
  t; R) i# O, [7 t0 R9 E3 v4 ]
答:  + y8 V& D: f. ]7 C( _6 B
Thread.suspend本身易于产生死锁.如果一个目标线程对某一关键系统资源进行了加锁操作,然后该线程被suspend,那么除非该线程被resume,否则其它线程都将无法访问该系统资源.如果另外一个线程将调用resume,使该线程继续运行,而在此之前,它也需要访问这一系统资源,则将产生死锁.  
2 ?3 Y( t* |+ `, v1 f: {1 e* E" c# L7 m$ T. H& s8 k
因此,在Java 2中,比较流行的方式是定义线程的状态变量,并使目标线程轮询该状态变量,当状态为悬挂状态时,可以使用wait()方法使之处于等待状态.一旦需要该线程继续运行,其它线程会调用notify()方法来通知它.  
9 i: z! p6 B2 h9 \  h: ]6 z0 `; m& r# h1 u9 V/ }# \! ?
问:  
" O$ L1 g/ j- t8 a使用JDBC编程,应如何控制结果集ResultSet的指针,使之能够上下移动,以及移动到结果集的第一行和最后一行?  
/ C9 {; X- p, |: Y9 Y( f# j
: _! Q  E+ `' p答:  , B1 P9 R- ?: L1 i% Y8 N
在JDK1.1中,ResultSet类中只定义了next()方法支持数据指针的下移.但在Java 2中,ResultSet类增加了如下方法支持数据指针的移动,包括:  
; a' H! k! \: |7 O" X/ P+ n1 G8 r* X6 d9 D7 T
1 q0 I. s6 P- I+ X
ResultSet.first():将数据指针移到结果集的第一行  ! _: o5 n, b& Z- Z/ \% |

5 P- F! g$ w7 d) T' @& o9 Z, W7 vResultSet.last(): 将数据指针移到结果集的最后一行  $ D( ^* X! o' _3 E
! k- b; `6 K, M
ResultSet.previous(): 将数据指针上移一行  " ]* B; s! k3 ~* k$ B
: {0 V6 G+ w: z* v- G

4 K5 J' ~3 h; g  x0 i5 h( |以上的方法定义在JDBC2.0的规范中,所有支持JDBC 2.0的JDBC驱动程序都可以支持上述方法.目前Intersolv和OpenLink等JDBC驱动程序厂商均有产品支持JDBC 2.0 .  8 E- v+ Q* h8 Y4 X

: j8 y) [# l: ]$ Q- B* W  x  X4 c( ]) ^# A% Q. Z/ N
问:  ; v0 Q8 E4 {  M
哪几种Web Server支持Servlet?如何使IIS支持Servlet?  " |9 b. _$ Z' p* g
5 ~# c* _4 m( I3 |1 h3 k
答:  
3 m- X1 X2 @* l9 A* O# P% T& ]6 U目前,支持Servlet的服务器端产品主要有: Sun公司的Java WebServer,Lotus DominoGo WebServer,BEA weblogic Tengah Server,Jigsaw,NetForge,AcmeServer和Mot Bays Jetty等.  $ `! |" B* `4 i

- q$ F2 F! i- M3 X* d% l此外,一些第三方厂商也开发了Servlet engine,以使其它WebServer(如Netscape Web Server,IIS等)能够运行Servlet,如LiveSoftware的Jrun(http://www.livesoftware.com/ products/jrun/)等.  
0 y3 p, a; {+ T7 h+ K4 Y3 J/ k3 `# _3 u
问:  - G- r# {; ?; O! d7 D* i. y1 ~8 ]
如何在Java应用中将图像存储到图像文件中?  ; ]* G6 B1 S! }6 z! d' ^
2 s/ c9 H. _- O4 s( B
答:    [* f( P" r( r
Java Advanced Imaging API(包含在Java Media API中)允许在Java应用中执行复杂的,高性能的图像处理.JAI API提供了存储图像的能力.目前,JAI API支持以下几种图像文件格式:BMP,JEPG,PNG,PNM,TIFF.下面给出了将图像存储到BMP文件的一段代码:  " ^) O7 P8 V/ I( }
) [) P  e+ ]) t. L- B" ~* n  H
2 R8 o+ |3 x4 {+ L! [" _3 Y
OutputStream os = new FileOutputStream(fileToWriteTo);  9 e; |1 U7 @) C7 D
5 L' O, l! u! e3 d/ T0 C/ ?( t) T
BMPEncodeParam param = new BMPEncodeParam();  ! w! T1 N/ C( w1 E  v1 f/ T5 A2 v

! |0 s6 G, H; D1 ~8 n  ?  |ImageEncoder enc = ImageCodec.createImageEncoder("BMP", os, param);  : r0 K1 O7 ?9 V2 i" N! V/ G2 u
, p6 P! M+ G5 `) Q& c
enc.encode(img);  
5 l. F1 X/ i8 C5 V1 }
9 L/ f9 x  E6 |' n8 s. B  S  Hos.close();  
! J: o) e6 Z9 E" K7 ]( B4 K7 n4 N- n
有关存储图像文件的编程指南请参考以下网页:  
: T) j+ v- r9 `6 h$ A  L! w5 ^; {3 N) \
http://java.sun.com/products/java-media/jai/forDevelopers/jai-guide/    T; S/ ~( I' d& B
! i7 q/ ~  [, A9 f- u  y

1 w2 \) H7 w3 n
5 C; Q! p" X8 R' d7 X7 ~, x' W6 o
; E9 Y  S" U5 Z2 _3 B& g0 q问:  
+ _" t, G. v$ {3 v9 q如何用Java语言向串口读写数据? font>  % c* i6 q6 U  ^

; y! s9 X3 i8 t7 Z* F% `' Q答:  
) L# K1 z+ G$ n% TSun公司的Java Communication API2.0可用于读写串口,它支持RS232串口和IEEE 1284 并口,提供了一种与平台无关的串/并口通信机制.  
: u: x5 U) L3 z0 m  b! [( E* V1 g7 L7 I: `
详细文档,请访问:<a href="http://java.sun.com/products/javacomm/" target="_blank" >http://java.sun.com/products/javacomm/</A>
作者: wangyu249    时间: 2006-11-21 15:02
<p>&nbsp; hehe</p>
作者: wl820609    时间: 2006-11-29 07:21
<p>顶!!!有最新的没/</p><p></p>
作者: deven1985    时间: 2010-1-6 00:44
楼主辛苦了,现在先顶下,以后慢慢看!




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5