`
gyabooks
  • 浏览: 22990 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

RMI原理展示-UI含源代码

    博客分类:
  • JAVA
阅读更多

博采众生我在上一篇文章中,简单地介绍了RMI的原理,这一篇文章我想在通过一个稍微复杂一点的例子,更好的向大家说明。读这篇文章需要你先参考我的上一篇文章: RMI(Remote Method Invocation)原理浅析

例子中,用到了javaUI的swing和事件处理,以及线程知识,如果你对这方面的知识不是太清楚的话,希望你能参考一下资料,非常简单 !

例子的思想就是通过在远程启动服务,客户端提交任务,处理完以后,把结果反馈给客户端完成任务。程序的功能就是计算加减乘除, 有六个文件,分别为:

 

  • AllCalculate.java,接口,定义了客户端和服务端共用的接口;
  • AllCalculateImpl.java,服务端接口实现;
  • AllCalculateServer.java,服务端服务提供者,它需要实例接口实现,导入到注册表中;
  • MyRMIExam.java,客户端启动
  • MyRMIGui.java,客户端UI,实现了加减乘除,分别在不同的线程里处理,是程序不会猛然间显得没有反应;
  • ServiceListFrame.java,使用在客户端,用以检索服务端机器的远程服务名字。
  •  

    tools包是我自己写的一个工具包,辅助我来验证客户的输入,有关这个包中的文本验证和窗体居中显示,请你参考我的三片文章: 文本控件内容录入限制(含源代码说明)(一) Java 文本控件内容录入限制(含源代码说明)(二) Java窗体居中显示。由于源代码比较长,在这里就是简单的罗列了: AllCalculate.java,AllCalculateServer.java和MyRMIExam.java代码清单,如果你需要参考完整的源代码,请你到CSDN资源下载中心下载,文件名称为:MyRMI.rar(搜索下载, 我得源代码中使用的UTF-8的编码格式,工程是Eclipse),如果你有任何问题的话,请给我留言。

    下面是程序运行的几幅演示图片,你可以在你的电脑上演示:

    博采众生

    所在环境的文件结构,方便你的实验

    博采众生

    Eclipse中的结构

    博采众生

    在Eclipse中启动设置,注意此时需要先启动rmiregistry服务环境

    博采众生

    客户端启动配置

    博采众生

    如果你没有安装Eclipse,需要手动命令行启动

    博采众生

    命令行启动客户端,注意此时client.policy放在exam目录下

    图片中,小三角加感叹号是由于我使用恶java的SecurityManager,你可以在源代码中注释掉这个功能。

    以下是几个程序源码清单:

     

    1. packagenet.csdn.blog.qb2049_xg;
    2. importjava.rmi.Remote;
    3. importjava.rmi.RemoteException;
    4. /**
    5. *AllCalculate.java
    6. *@authorUlyssesMa
    7. *@date2008-9-9
    8. *Remote在这里标识远程对象
    9. */
    10. publicinterfaceAllCalculateextendsRemote
    11. {
    12. //加
    13. publicfloatadd(floata,floatb)throwsRemoteException;
    14. //减
    15. publicfloatminus(floata,floatb)throwsRemoteException;
    16. //除
    17. publicfloatdiv(floata,floatb)throwsRemoteException;
    18. //乘
    19. publicfloatmul(floata,floatb)throwsRemoteException;
    20. }

    *****************************************************************************

     

     

    1. packagenet.csdn.blog.qb2049_xg;
    2. importjava.rmi.AccessException;
    3. importjava.rmi.AlreadyBoundException;
    4. importjava.rmi.RemoteException;
    5. importjava.rmi.registry.LocateRegistry;
    6. importjava.rmi.registry.Registry;
    7. /**
    8. *AllCalculateServer.java
    9. *@authorUlyssesMa
    10. *@date2008-9-9
    11. */
    12. publicclassAllCalculateServer{
    13. publicstaticvoidmain(String[]args){
    14. try{
    15. //实现要导出的远程对象,它来完成运算(创建远程对象实例)
    16. AllCalculateImplallCalculate=newAllCalculateImpl();
    17. //获得本地的(RMI,要求是在rmiregistry启动情况下)注册表
    18. Registryrg=LocateRegistry.getRegistry();
    19. //实现对象的绑定,完成远程对象的注册工作
    20. rg.bind("allCalculate1",allCalculate);
    21. //状态提示
    22. System.out.println("实现所有方法的服务现在已成功启动!");
    23. }catch(NullPointerExceptionne){
    24. System.out.println("服务端出现了异常,可能是bind方法中name或是对象为空。\n"+ne.getMessage());
    25. }catch(AlreadyBoundExceptionabe){
    26. System.out.println("服务端出现了异常,可能是bind名字已被占用。\n"+abe.getMessage());
    27. }catch(AccessExceptionae){
    28. System.out.println("服务端出现了异常,可能是访问被拒绝。\n"+ae.getMessage());
    29. }catch(RemoteExceptionre){
    30. System.out.println("服务端出现了异常,可能是连接通信出现了问题。\n"+re.getMessage());
    31. }
    32. }
    33. }

    ************************************************************************************

     

     

    1. packagenet.csdn.blog.qb2049_xg;
    2. importjava.awt.BorderLayout;
    3. importjava.awt.Color;
    4. importjava.awt.Container;
    5. importjava.awt.GridBagConstraints;
    6. importjava.awt.GridBagLayout;
    7. importjava.awt.event.ActionEvent;
    8. importjava.awt.event.ActionListener;
    9. importjava.rmi.NotBoundException;
    10. importjava.rmi.RemoteException;
    11. importjava.rmi.registry.LocateRegistry;
    12. importjava.rmi.registry.Registry;
    13. importjavax.swing.JButton;
    14. importjavax.swing.JFrame;
    15. importjavax.swing.JLabel;
    16. importjavax.swing.JMenu;
    17. importjavax.swing.JMenuBar;
    18. importjavax.swing.JMenuItem;
    19. importjavax.swing.JOptionPane;
    20. importjavax.swing.JPanel;
    21. importjavax.swing.JScrollPane;
    22. importjavax.swing.JTextArea;
    23. importjavax.swing.JTextField;
    24. importjavax.swing.border.LineBorder;
    25. importnet.csdn.blog.qb2049_xg.tools.JTextHelp;
    26. importnet.csdn.blog.qb2049_xg.tools.MidScr;
    27. /**
    28. *MyRMIGui.java
    29. *@authorUlyssesMa
    30. *
    31. */
    32. publicclassMyRMIGuiextendsJFrameimplementsActionListener
    33. {
    34. //序列化标识使用
    35. privatestaticfinallongserialVersionUID=2049L;
    36. //窗体布局面板的定义
    37. privateJPaneltitle_p=newJPanel();
    38. privateJPanelbody_p=newJPanel();
    39. privateJPanelbottom_p=newJPanel();
    40. privateJTextFieldaddA_t,addB_t,minusA_t,minusB_t,divA_t,divB_t,mulA_t,mulB_t;
    41. privateJTextFieldaddResult_t,addServer_t,minusResult_t,minusServer_t,divResult_t,
    42. divServer_t,mulResult_t,mulServer_t,serviceAdd_t,serviceMinus_t,serviceMul_t,serviceDiv_t;
    43. //分
    44. privateServiceListFramelistFrame;
    45. //一些关键性部件声明
    46. privateJLabeltitle_l=newJLabel("<html><fontcolor=redsize=6>RMI加、减、乘、除实验</font></html>");
    47. privateJLabelexception_l=newJLabel("异常处理:");
    48. privateJTextAreaexception_ta=newJTextArea(10,70);
    49. //构造函数
    50. publicMyRMIGui()
    51. {
    52. //标题部分显示的设置
    53. title_p.setAlignmentX(JPanel.CENTER_ALIGNMENT);
    54. title_p.add(title_l);
    55. //主体部分的设置
    56. GridBagLayoutgbl1=newGridBagLayout();
    57. body_p.setLayout(gbl1);
    58. GridBagConstraintsc1=newGridBagConstraints();
    59. //表题说明
    60. JLabelnumberA,numberB,result,equal,operate,server,start,service;
    61. numberA=newJLabel("数A");
    62. numberA.setHorizontalAlignment(JLabel.CENTER);
    63. numberB=newJLabel("数B");
    64. numberB.setHorizontalAlignment(JLabel.CENTER);
    65. result=newJLabel("结果");
    66. result.setHorizontalAlignment(JLabel.CENTER);
    67. equal=newJLabel("等号");
    68. equal.setHorizontalAlignment(JLabel.CENTER);
    69. operate=newJLabel("操作符");
    70. operate.setHorizontalAlignment(JLabel.CENTER);
    71. server=newJLabel("服务器");
    72. server.setHorizontalAlignment(JLabel.CENTER);
    73. service=newJLabel("服务名称");
    74. service.setHorizontalAlignment(JLabel.CENTER);
    75. start=newJLabel("开始");
    76. start.setHorizontalAlignment(JLabel.CENTER);
    77. c1.fill=GridBagConstraints.VERTICAL;
    78. c1.gridx=0;
    79. c1.gridy=0;
    80. body_p.add(numberA,c1);
    81. c1.gridx=1;
    82. body_p.add(operate,c1);
    83. c1.gridx=2;
    84. body_p.add(numberB,c1);
    85. c1.gridx=3;
    86. body_p.add(equal,c1);
    87. c1.gridx=4;
    88. body_p.add(result,c1);
    89. c1.gridx=5;
    90. body_p.add(server,c1);
    91. c1.gridx=6;
    92. body_p.add(service,c1);
    93. c1.gridx=7;
    94. body_p.add(start,c1);
    95. //加运算UI
    96. addA_t=newJTextField(10);
    97. addB_t=newJTextField(10);
    98. newJTextHelp(addA_t,JTextHelp.NUMBER).insertCheck();
    99. newJTextHelp(addB_t,JTextHelp.NUMBER).insertCheck();
    100. addResult_t=newJTextField(10);
    101. serviceAdd_t=newJTextField(10);
    102. addServer_t=newJTextField(15);
    103. JButtonaddStart_b=newJButton("开始计算");
    104. addStart_b.addActionListener(this);
    105. addStart_b.setActionCommand("add");
    106. JLabeladd_l=newJLabel("+");
    107. add_l.setHorizontalAlignment(JLabel.CENTER);
    108. JLabeladdEqual_l=newJLabel("=");
    109. addEqual_l.setHorizontalAlignment(JLabel.CENTER);
    110. c1.gridx=0;
    111. c1.gridy=1;
    112. body_p.add(addA_t,c1);
    113. c1.gridx=1;
    114. body_p.add(add_l,c1);
    115. c1.gridx=2;
    116. body_p.add(addB_t,c1);
    117. c1.gridx=3;
    118. body_p.add(addEqual_l,c1);
    119. c1.gridx=4;
    120. body_p.add(addResult_t,c1);
    121. c1.gridx=5;
    122. body_p.add(addServer_t,c1);
    123. c1.gridx=6;
    124. body_p.add(serviceAdd_t,c1);
    125. c1.gridx=7;
    126. body_p.add(addStart_b,c1);
    127. //减运算UI
    128. minusA_t=newJTextField(10);
    129. minusB_t=newJTextField(10);
    130. newJTextHelp(minusA_t,JTextHelp.NUMBER).insertCheck();
    131. newJTextHelp(minusB_t,JTextHelp.NUMBER).insertCheck();
    132. minusResult_t=newJTextField(10);
    133. minusServer_t=newJTextField(15);
    134. serviceMinus_t=newJTextField(10);
    135. JButtonminusStart_b=newJButton("开始计算");
    136. minusStart_b.addActionListener(this);
    137. minusStart_b.setActionCommand("minus");
    138. JLabelminus_l=newJLabel("-");
    139. minus_l.setHorizontalAlignment(JLabel.CENTER);
    140. JLabelminusEqual_l=newJLabel("=");
    141. minusEqual_l.setHorizontalAlignment(JLabel.CENTER);
    142. c1.gridx=0;
    143. c1.gridy=2;
    144. body_p.add(minusA_t,c1);
    145. c1.gridx=1;
    146. body_p.add(minus_l,c1);
    147. c1.gridx=2;
    148. body_p.add(minusB_t,c1);
    149. c1.gridx=3;
    150. body_p.add(minusEqual_l,c1);
    151. c1.gridx=4;
    152. body_p.add(minusResult_t,c1);
    153. c1.gridx=5;
    154. body_p.add(minusServer_t,c1);
    155. c1.gridx=6;
    156. body_p.add(serviceMinus_t,c1);
    157. c1.gridx=7;
    158. body_p.add(minusStart_b,c1);
    159. //除运算UI
    160. divA_t=newJTextField(10);
    161. divB_t=newJTextField(10);
    162. newJTextHelp(divA_t,JTextHelp.NUMBER).insertCheck();
    163. newJTextHelp(divB_t,JTextHelp.NUMBER).insertCheck();
    164. divResult_t=newJTextField(10);
    165. divServer_t=newJTextField(15);
    166. serviceDiv_t=newJTextField(10);
    167. JButtondivStart_b=newJButton("开始计算");
    168. divStart_b.setActionCommand("div");
    169. divStart_b.addActionListener(this);
    170. JLabeldiv_l=newJLabel("÷");
    171. div_l.setHorizontalAlignment(JLabel.CENTER);
    172. JLabeldivEqual_l=newJLabel("=");
    173. divEqual_l.setHorizontalAlignment(JLabel.CENTER);
    174. c1.gridx=0;
    175. c1.gridy=3;
    176. body_p.add(divA_t,c1);
    177. c1.gridx=1;
    178. body_p.add(div_l,c1);
    179. c1.gridx=2;
    180. body_p.add(divB_t,c1);
    181. c1.gridx=3;
    182. body_p.add(divEqual_l,c1);
    183. c1.gridx=4;
    184. body_p.add(divResult_t,c1);
    185. c1.gridx=5;
    186. body_p.add(divServer_t,c1);
    187. c1.gridx=6;
    188. body_p.add(serviceDiv_t,c1);
    189. c1.gridx=7;
    190. body_p.add(divStart_b,c1);
    191. //乘运算UI
    192. mulA_t=newJTextField(10);
    193. mulB_t=newJTextField(10);
    194. newJTextHelp(mulA_t,JTextHelp.NUMBER).insertCheck();
    195. newJTextHelp(mulB_t,JTextHelp.NUMBER).insertCheck();
    196. mulResult_t=newJTextField(10);
    197. mulServer_t=newJTextField(15);
    198. serviceMul_t=newJTextField(10);
    199. JButtonmulStart_b=newJButton("开始计算");
    200. mulStart_b.addActionListener(this);
    201. mulStart_b.setActionCommand("mul");
    202. JLabelmul_l=newJLabel("×");
    203. mul_l.setHorizontalAlignment(JLabel.CENTER);
    204. JLabelmulEqual_l=newJLabel("=");
    205. mulEqual_l.setHorizontalAlignment(JLabel.CENTER);
    206. c1.gridx=0;
    207. c1.gridy=4;
    208. body_p.add(mulA_t,c1);
    209. c1.gridx=1;
    210. body_p.add(mul_l,c1);
    211. c1.gridx=2;
    212. body_p.add(mulB_t,c1);
    213. c1.gridx=3;
    214. body_p.add(mulEqual_l,c1);
    215. c1.gridx=4;
    216. body_p.add(mulResult_t,c1);
    217. c1.gridx=5;
    218. body_p.add(mulServer_t,c1);
    219. c1.gridx=6;
    220. body_p.add(serviceMul_t,c1);
    221. c1.gridx=7;
    222. body_p.add(mulStart_b,c1);
    223. //状态初始化
    224. addResult_t.setEditable(false);
    225. minusResult_t.setEditable(false);
    226. mulResult_t.setEditable(false);
    227. divResult_t.setEditable(false);
    228. //异常问题的处理
    229. GridBagLayoutgbl=newGridBagLayout();
    230. bottom_p.setLayout(gbl);
    231. GridBagConstraintsc=newGridBagConstraints();
    232. c.fill=GridBagConstraints.NONE;
    233. c.gridx=0;
    234. c.gridy=0;
    235. bottom_p.add(exception_l,c);
    236. c.gridx=5;
    237. JButtonclear_b=newJButton("清空");
    238. clear_b.addActionListener(this);
    239. clear_b.setActionCommand("clear");
    240. bottom_p.add(clear_b,c);
    241. exception_ta.setBorder(newLineBorder(newColor(0,0,0)));
    242. exception_ta.setLineWrap(true);
    243. JScrollPanescrollPane=newJScrollPane(exception_ta);
    244. c.fill=GridBagConstraints.HORIZONTAL;
    245. c.gridx=0;
    246. c.gridy=1;
    247. c.gridwidth=6;
    248. bottom_p.add(scrollPane,c);
    249. //设置菜单栏
    250. JMenuBarjmb=newJMenuBar();
    251. JMenuhelp_m=newJMenu("帮助");
    252. JMenuItemlistService=newJMenuItem("浏览已注册的服务");
    253. listService.addActionListener(this);
    254. listService.setActionCommand("list");
    255. JMenuItemexit=newJMenuItem("退出");
    256. exit.addActionListener(this);
    257. exit.setActionCommand("exit");
    258. help_m.add(listService);
    259. help_m.add(exit);
    260. jmb.add(help_m);
    261. //加载面板
    262. this.setJMenuBar(jmb);
    263. Containerrp=this.getContentPane();
    264. rp.add(title_p,BorderLayout.NORTH);
    265. rp.add(body_p,BorderLayout.CENTER);
    266. rp.add(bottom_p,BorderLayout.SOUTH);
    267. //设置窗体展示宽度
    268. this.setSize(800,450);
    269. //设置显示位置
    270. MidScrms=newMidScr(this);
    271. this.setLocation(ms.getX(),ms.getY());
    272. //设置标题
    273. this.setTitle("测试JavaRMI的使用问题");
    274. //关闭点击后的处理
    275. this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    276. this.setVisible(true);
    277. this.validate();
    278. }
    279. //事件的处理
    280. publicvoidactionPerformed(ActionEvente)
    281. {
    282. //add,minus,div,mulcommands
    283. exception_ta.setForeground(newColor(255,0,0));
    284. //加事件的处理
    285. if(e.getActionCommand().equals("add"))
    286. {
    287. Stringarg1=addA_t.getText().trim();
    288. Stringarg2=addB_t.getText().trim();
    289. Stringhost=addServer_t.getText().trim();
    290. Stringservice=serviceAdd_t.getText().trim();
    291. if(arg1.equals("")&&arg2.equals(""))
    292. {
    293. JOptionPane.showMessageDialog(this,"参与计算的两个数字不能为空,请检查你的输入,谢谢!",
    294. "远程调用",JOptionPane.INFORMATION_MESSAGE);
    295. return;
    296. }
    297. newThread(newLoadRMI(host,arg1,arg2,service,e.getActionCommand())).start();
    298. }
    299. //减事件的处理
    300. if(e.getActionCommand().equals("minus"))
    301. {
    302. Stringarg1=minusA_t.getText().trim();
    303. Stringarg2=minusB_t.getText().trim();
    304. Stringhost=minusServer_t.getText().trim();
    305. Stringservice=serviceMinus_t.getText().trim();
    306. if(arg1.equals("")&&arg2.equals(""))
    307. {
    308. JOptionPane.showMessageDialog(this,"参与计算的两个数字不能为空,请检查你的输入,谢谢!",
    309. "远程调用",JOptionPane.INFORMATION_MESSAGE);
    310. return;
    311. }
    312. newThread(newLoadRMI(host,arg1,arg2,service,e.getActionCommand())).start();
    313. }
    314. //乘事件的处理
    315. if(e.getActionCommand().equals("mul"))
    316. {
    317. Stringarg1=mulA_t.getText().trim();
    318. Stringarg2=mulB_t.getText().trim();
    319. Stringhost=mulServer_t.getText().trim();
    320. Stringservice=serviceMul_t.getText().trim();
    321. if(arg1.equals("")&&arg2.equals(""))
    322. {
    323. JOptionPane.showMessageDialog(this,"参与计算的两个数字不能为空,请检查你的输入,谢谢!",
    324. "远程调用",JOptionPane.INFORMATION_MESSAGE);
    325. return;
    326. }
    327. newThread(newLoadRMI(host,arg1,arg2,service,e.getActionCommand())).start();
    328. }
    329. //除事件的处理
    330. if(e.getActionCommand().equals("div"))
    331. {
    332. Stringarg1=divA_t.getText().trim();
    333. Stringarg2=divB_t.getText().trim();
    334. Stringhost=divServer_t.getText().trim();
    335. Stringservice=serviceDiv_t.getText().trim();
    336. if(arg1.equals("")&&arg2.equals(""))
    337. {
    338. JOptionPane.showMessageDialog(this,"参与计算的两个数字不能为空,请检查你的输入,谢谢!",
    339. "远程调用",JOptionPane.INFORMATION_MESSAGE);
    340. return;
    341. }
    342. newThread(newLoadRMI(host,arg1,arg2,service,e.getActionCommand())).start();
    343. }
    344. //清理文本框按钮事件
    345. if(e.getActionCommand().equals("clear")){
    346. exception_ta.setText("");
    347. }
    348. //退出菜单事件处理
    349. if(e.getActionCommand().equals("exit")){
    350. System.exit(HIDE_ON_CLOSE);
    351. }
    352. //查看注册服务菜单事件
    353. if(e.getActionCommand().equals("list")){
    354. if(listFrame==null)
    355. listFrame=newServiceListFrame();
    356. else
    357. listFrame.setVisible(true);
    358. }
    359. }
    360. //完成各种方法调用,在这里使用了多线程的方法,可以多个任务同时的进行,不会有等待的感觉
    361. classLoadRMIimplementsRunnable
    362. {
    363. Stringhost,arg1,arg2,service;
    364. StringactionCommand;
    365. publicLoadRMI(Stringhost,Stringarg1,Stringarg2,Stringservice,StringactionCommand){
    366. this.arg1=arg1;
    367. this.arg2=arg2;
    368. this.host=host;
    369. this.service=service;
    370. this.actionCommand=actionCommand;
    371. }
    372. publicvoidrun(){
    373. try{
    374. //如果host的值是null的话,那么系统就默认调用本地远程方法
    375. Registryrg=LocateRegistry.getRegistry(host);
    376. AllCalculateac=(AllCalculate)rg.lookup(service);
    377. floata=Float.valueOf(arg1).floatValue();
    378. floatb=Float.valueOf(arg2).floatValue();
    379. //根据事件名称调用方法
    380. if(this.actionCommand.equals("add")){
    381. addResult_t.setText(String.valueOf(ac.add(a,b)));
    382. }
    383. if(this.actionCommand.equals("minus")){
    384. minusResult_t.setText(String.valueOf(ac.minus(a,b)));
    385. }
    386. if(this.actionCommand.equals("mul")){
    387. mulResult_t.setText(String.valueOf(ac.mul(a,b)));
    388. }
    389. if(this.actionCommand.equals("div")){
    390. divResult_t.setText(String.valueOf(ac.div(a,b)));
    391. }
    392. }catch(NullPointerExceptionnpe){
    393. exception_ta.append("调用的服务名称为空"+npe.getMessage()+"\n");
    394. }catch(NotBoundExceptionnbe){
    395. exception_ta.append("调用的服务不存在,请检查你的输入"+nbe.getMessage()+"\n");
    396. }
    397. catch(RemoteExceptionre){
    398. exception_ta.append("调用远程方法时出现了问题,情况可能是:"+re.getMessage()+"\n");
    399. }
    400. }
    401. }
    402. }

     

    如果你对这个小例子感兴趣的话,请你到CSDN资源中心下载!

    分享到:
    评论

    相关推荐

      Thinking in Java(中文版 由yyc,spirit整理).chm

      8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重新使用接口 1.5.1 改善...

      JAVA_Thinking in Java(中文版 由yyc,spirit整理).chm

      8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重新使用接口 1.5.1 改善...

      J2EE应用开发详解

      内容为J2EE应用开发详解中的源代码 第1章 Java Web应用开发简介 1 1.1 Java EE应用概述 1 1.2 Java EE概念 1 1.2.1 Java EE多层模型 1 1.2.2 Java EE体系结构 2 1.3 Java EE的核心API与组件 4 1.4 Web服务器和应用...

      Think in Java(中文版)chm格式

      8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重新使用接口...

      Java初学者入门教学

      8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重新使用接口 1.5.1 改善...

      JAVA_Thinking in Java

      8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重新使用接口 1.5.1 改善...

      ThinkInJava

      8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重新使用接口 1.5.1 改善...

      java 编程入门思考

      8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重新使用接口 1.5.1 改善...

      thinkinjava

      8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重新使用接口 1.5.1 改善...

      Thinking in Java简体中文(全)

      8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重新使用接口 1.5.1 改善...

      java联想(中文)

      8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重新使用接口 1.5.1 改善...

      Thinking in Java 中文第四版+习题答案

      8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重新使用接口 1.5.1 改善...

    Global site tag (gtag.js) - Google Analytics