第1 章 Java 程序设计概述 1、 Java 和C++最大的不同在于Java 采用的指针模型可以消除重写内存和损坏数据的可能性。 2、虚拟机有一个选项,可以将使用最频繁的字节码序列翻译成机器码,这一过程被称为即 时编译。 3、在Java 中,数据类型具有固定的大小。 第2 章 Java 程序设计环境 1、JDK 目录树 2、运行applet 格式 javac filename.java appletviewer filename.html第3 章 Java 基本的程序设计结构 1、在一个单词的中间使用大写字母的方式称为骆驼命名法。 2、根据Java 语言规范,main 方法必须声明为public。(在JavaSE1.4 及以后的版本中将强 制main 方法是public 的) 3、在Java 中,/* */注释不能嵌套。 4、在Java 中,整型的范围与运行Java 代码的机器无关。 5、Java 没有任何无符号类型(unsigned type)。 6、 浮点数值不适用于禁止出现舍入误差的金融计算中。例如,命令System.out.println(2.0-1.1) 将打印出0.8999999999999999,而不是人们想象的0.9。 7、整数被0 除将会产生一个异常,而浮点数被0 除将会得到无穷大或NaN 结果。 8、Java 提供了计算用于表示 和e 常量的近似值: Math.PI Math.E 9、“==”运算符只能够确定两个字符串是否放置在同一个位置上。 10、输入是可见的,所以Scanner类不适用于从控制台读取密码。Console类实现了这个目的。要想读取一个密码,可以采用下列代码: Console cons = System.console(); String username = cons.readLine("User name: "); char[] passwd = cons.readPassword("Password: "); 11、Java SE5.0沿用了C语言库函数中的printf方法。 12、java.math包中的BigInteger和BigDecimal可以处理包含任意长度数字序列的数值。BigInteger类实现了任意精度的整数运算,BigDecimal实现了任意精度的浮点数运算。不能使用人们熟悉的算术运算符(如:+和*)处理大数值。而需要使用大数值类中的add和multiply方法。 ◆使用静态的valueOf()方法可以将普通的数值转换为大数值: BigInteger a = BigInteger.valueOf(4); 13、Java SE 5.0增加了For each循环,格式: for(varible:collection){ statement; } 利用For each访问二维数组a的所有元素: for(Type[] row:a){ for(Type[] value:row){ do something with value; } } 14、利用Arrays类的toString方法,可以更加简单的打印一维数组中的所有值。打印多维数组,需要调用Arrays.deepToString()(此方法不能打印一维数组)。 15、在Java中,允许数组长度为0。数组长度为0与null不同。第4章 对象与类 1、使用通配符“*”调用Java编译器: javac Employee*.java 于是,所有与通配符匹配的源文件都将被编译成类文件。 2、所有的Java对象都是在堆中构造的。 3、不要编写返回引用可变对象的访问器方法。破坏了封装性。如果需要返回一个可变对象的引用,应该首先对它进行克隆。 4、建议使用类名,而不是对象来调用静态方法。 5、Java程序设计语言对对象采用的并不是引用调用。 6、仅当类没有提供任何构造器的时候,系统才会提供一个默认的构造器。 7、在Java中,一个构造器不能调用另一个构造器! 8、可以使用Java编写一个没有main方法的“Hello World”程序: public class HelloWolrd { static { System.out.println("Hello World!"); System.exit(0);//使其不报错! } } 9、 在实际应用中,不要依赖于使用finalize方法回收任何短缺的资源,这是因为很难知道个方法社么时候才能够调用。 10、Sun公司建议将公司的因特网域名(因其独一无二)以逆序的形式作为包名。 11、从Java SE5.0开始,import语句不仅可以导入类,还增加了导入静态方法和静态域的功能。(个人觉得少用为好,因其使代码艰涩难懂) 12、注释: (1)类注释应该放在import语句之后,类定义之前; (2)每一个方法注释应该放在所描述的方法之前。 13、这些技巧可以使设计出来的类更具有OOP的专业水准: (1)一定将数据设计为私有。 (2)一定要对数据初始化。 (3)不要在类中使用过多的基本数据类型。 (4)不是所有的域都需要独立的域访问器和域更改器。 (5)使用标准格式进行类的定义。 (6)将职责过多的类进行分解。 (7)类名和方法要能够体现他们的职责。第5章 继承 1、在Java中,所有的继承都是公有继承。 2、super()只能作为子类构造器的第一句出现! 3、一个对象变量可以引用多种实际类型的现象被称为多态。在运行时能够自动地选择调用哪个方法的现象称为动态绑定。 4、在Java中,子类数组的引用可以转换成超类数组的引用。 5、如果是private方法、static方法、final方法或者构造器,那么编译器将可以准确地知道应该调用哪个方法,这种方式称为静态调用。 6、 在覆盖一个方法的时候,子类方法不能低于超类方法的可见性。如果超类方法是public, 子类方法一定要声明为public。 7、如果将一个类声明为final,只有其中的方法自动地成为final,而不包括域。 8、将一个子类的引用赋给一个超类变量,编译器是允许的。但将一个超类的引用赋给一个子类变量,必须进行类型转换,这样才能够通过运行时的检查。 (1)只能在继承层次内进行类型转换; (2)在将超类转换成子类之前,应该使用instanceof进行检查。 9、包含一个或多个抽象方法的类本身必须被声明为抽象的。 10、在Java中,只有基本类型不是对象。 11、所有的基本类型都有一个与之对应的类。Integer、Long、Float、Double、Short、Byte、Character、Void和Boolean(前6个类派生于公共的超类Number)。对象包装器类是不可变的,即一旦构造了包装器,就不允许更改包装在其中的值。对象包装器类还是final,因此不能定义它们的子类。 12、在比较两个枚举类型的值时,永远不需要调用equals,而直接使用“==”就可以了。 13、能够分析类能力的程序被称为反射。 14、一个设计继承关系类的建议: (1)将公共操作和域放在超类。 (2)不要使用受保护的域。 (3)使用继承实现“is-a”关系。 (4)除非所有的继承的方法都有意义,否则不要使用继承。 (5)在覆盖方法时,不要改变预期的行为。 (6)使用多态,而非类型信息。 (7)不要过多地使用反射。第6章 接口与内部类 1、在接口中可以定义常量。但接口绝不能含有实例域,也不能在接口中实现方法。 2、不能使用new运算符实例化一个接口,却能声明接口的变量。 3、接口中的方法都自动地被设置为public,接口中的域自动被设为public static final。 4、在Object类中,clone方法被声明为protected。所有的数组类型均包含一个clone方法,这个方法被设为public,而不是protected的。 5、编译器将会把内部类翻译成用$(美元符号)分隔外部类名与内部类名的常规类文件。 6、final变量只能够被赋值一次(在定义的时候或构造方法中)。在定义final变量的时候,不必进行初始化。将一个类或数组定义为final时,对象的引用不能更改,对象的值能更改! 7、声明在接口中的内部类自动成为static和public。第7章 图形程序设计 1、抽象窗口工具箱(Abstract Window Toolkit,AWT)。 2、Swing没有完全替代AWT,而是基于AWT架构之上。 3、JFrame是极少数几个不绘制在画布上的Swing组件之一。它的修饰部件(按钮、标题栏、图标等)由用户的窗口系统绘制,而不是由Swing绘制。在默认情况下,框架的大小为0×0。 4、在初始化语句结束后,main方法退出。退出main并没有终止程序,终止的只是主线程。 5、关闭框架装饰:frame.setUndecorated(true); 禁止改变框架大小:frame.setResizable(flase); 6、对于框架来说,setLocation和setBounds中的坐标均相对于整个屏幕。在容器中包含的组件所指的坐标均相对于容器。 7、获取属性类方法以get开头(一个例外,对于类型为boolean的属性,获取类方法由is开头);设置属性类方法以set开头; 8、获取屏幕的大小: Toolkit kit = Toolkit.getDefaultToolkit(); Dimension screenSize = kit.getScreenSize(); int WIDTH = screenSize.width; int HEIGHT = screenSize.height; 9、调用pack方法设置框架大小,框架将被设置为刚好能够放置所有组件的大小。 10、JFrame中有四层面板。 11、如果需要强制刷新屏幕,就需要调用repaint方法。 12、Java 2D图形采用的是浮点坐标。 13、Rectangle2D方法的参数和返回值均为double类型。 14、java.awt.Color类中提供了13个预定义的常量,它们分别表示13中标准颜色。 15、Color类中的brighter()方法和darker()方法的功能分别是加亮或变暗当前的颜色。 16、Color(int r, int g, int b):创建一个颜色对象。参数: r:红色值(0-255) g:绿色值(0-255) b:蓝色值(0-255) 17、字体名由字体家族名和一个可选的“Bold”后缀组合。Sun JDK包含3种字体,它们是“Lucida Sans”,“Lucida Bright”和“Lucida SansTypewriter”。第8章 事件处理 1、在按钮示例中,使用的ActionListener接口并不仅限于按钮点击事件。它可以应用于很多情况: (1)当采用鼠标双击的方式选择了列表框中的一个选项时; (2)当选择一个菜单项时; (3)当在文本域中敲击ENTER键时; (4)对于一个Timer组件来说,当到达指定的时间间隔时。 2、(1)Object getSource():返回发生事件的对象引用。 (2)String getActionCommand():返回与这个动作事件相关的命令字符串。 3、Swing程序只在启动时读取一次swing.propertise文件(在Java安装的子目录jre/lib下)。 4、当程序用户试图关闭一个框架窗口时,JFrame对象就是WindowEvent的事件源。 WindowListener接口中包含7个方法。WindowListener接口: public interface WindowListener{ void windowOpened(WindowEvent e); void windowClosing(WindowEvent e); void windowClosed(WindowEvent e); void windowIconified(WindowEvent e); void windowDeiconified(WindowEvent e); void windowActivated(WindowEvent e); void windowDeactvated(WindowEvent e); } ◆仅当调用hide或dispose方法后窗口才能够关闭。 5、void WindowStateChanged(WindowEvent event):窗口被极大化、图标化或恢复为正常大小时调用这个方法。 6、可以利用Toolkit类中的createCustomCursor方法自定义光标类型: Toolkit tk = Toolkit.getDefaultToolkit(); Image img = tk.getImage("src\\note\\光标.gif"); Cursor dynamiteCursor = tk.createCustomCursor(img, new Point(10,10), "src\\note\\光标.gif"); 7、只有鼠标在一个组件内部停留才会调用mouseMoved方法。即使鼠标拖动到组件外面,mouseDragged方法也会被调用。 8、所有的事件都是由java.util包中的EventObject类扩展而来的。第9章 Swing用户界面组件 1、没有一种模式能够使用与所有情况。 2、每个Swing组件都有一个相关的后缀为UI的视图对象,但并不是所有的Swing组件都有专门的控制器对象。 3、JFrame是Container的子类,也是Component的子类,但却不能放在其它容器内。 4、边框布局管理器(BorderLayout)是每个JFrame的内容窗格的默认布局管理器。当布局管理器为BorderLayout时,当容器被收缩时,边缘组件的厚度不会改变,而中部组件的大小会发生变化。 5、面板的默认布局管理器是FlowLayout。 6、在JTextField的构造器中设定的宽度并不是用户能输入的字符个数的上限。当文本长度超过文本域长度时输入就会滚动。 7、revalidate方法会重新计算容器内所有组件的大小,并且对它们重新进行布局。它并不是马上就改变组件大小,而是给这个组件加一个需要改变大小的标记。 8、如果想要将getText方法返回的文本域中的内容的前后空格去掉,就应该调用trim()方法。 9、从JDK1.3开始,可以在按钮、标签和菜单项上使用无格式文本或HTML文本。 ◆包含HTML标签的第一个组件需要延迟一段时间才能显示出来。 10、void setEchoChar(char echo):为密码域设置回显字符。 11、JTextArea组件只显示无格式的文本,没有字体或者格式设置。如果想要显示格式化文本(如HTML或者RTF),就需要使用JeditorPane和JTextPane。 12、当复选框获得焦点时,用户也可以通过按空格键来切换选择。 13、复选框为正方形;单选框为圆形。 14、调用BorderFactory的静态方法创建边框。 15、调用setEditable方法可以让组合框可编辑。注意,编辑只会影响当前项,而不会改变列表内容。 16、滑块(JSlider)允许进行连续值的选择。 17、弹出菜单的显示,如:popup.show(panel,x,y); 18、启用或禁用菜单项需要调用setEnable方法。 ◆在显示菜单之前禁用菜单项是一种明智的选择,但这种方式不适用与带有加速键的菜单项。 19、工具栏的特殊之处在于可以将它随处移动。可以将它拖拽到框架的四个边框上。 ◆工具栏只有位于采用边框布局或者任何支持North、East、South和West约束布局管理器的容器内才能够被拖拽。 20、在默认情况下,工具栏最初为水平的。 21、可以使用setToolTipText()方法将工具提示添加到JComponent上。 22、在2005年,NetBeans开发队伍发明了Matisse技术,这种技术将布局工具与布局管理器与 合起来。 23、网格组布局(GridBagLayout)是所有布局管理器之首。可以将相邻的单元合并以适应较大的组件。 24、任何高级技术都源于奇特的想法之中。 25、可能想确保文本域和密码域的宽度相等。在Matisse中,选择这两个组件,然后点击鼠标右键,并从菜单中Same Size->Same Width。 26、将一个组件定位到某个绝对定位的步骤: (1)将布局管理器设置为null。 (2)将组件添加到容器中。 (3)指定想要放置的位置和大小。 27、Swing的遍历顺序:从左至右,从上至下。 28、在遍历大子容器的最后一个元素之后,焦点并不回到第一个元素上,而是跳到容器的后继组件上。 29、AWT分为模式对话框和无模式对话框。模式对话框是指在结束对它的处理之前,不允许用户与应用程序的其余窗口进行交互。 30、JOptionPane有4个用于显示对话框的静态方法: (1)showMessageDialog:显示一条消息并等待用户点击OK。 (2)showConfirmDialog:显示一条消息并等待用户确认。 (3)showOptionDialog:显示一条消息并获得用户在一组选项中的选择。 (4)showInputDialog:显示一条消息并获得用户输入的一行文本。 31、拥有者框架控制对话框的显示位置,如果将拥有者标识为null,那么对话框将由一个隐藏框架所拥有。第10章 部署应用程序和applet 1、 Java归档(JAR,Java Archive)文件是压缩的,它使用ZIP压缩格式。 2、 清单文件的最后一行必须以换行符结束。否则,清单文件将无法被正确地读取。 3、 在沙箱中的程序有下列限制: (1)不能运行任何本地的可执行程序。 (2)不能从本地计算机文件系统中读取任何信息,也不能往本地计算机文件系统中写入任何信息。 (3)不能查看除Java版本信息和少数几个无害的操作系统详细信息外的任何有关本地计算机的信息。特别是,在沙箱中的代码不能查看用户名、e-mail地址等信息。 (4)远程加载的程序不能与除下载程序所在的服务器之外的让任何主机通信。 (5)所有弹出式窗口都会带一个警告消息。 4、JNLP(java网络加载协议)API允许未签名的应用程序在沙箱中运行,同时通过一种安全的途径访问本地资源。 5、如果applet包含Swing组件,就必须扩展于Japplet类。 6、applet: (1)void init():首次加载applet时调用这个方法。覆盖这个方法,并且将所有的初始化代码放在这里。 (2)void start():覆盖这个方法,将用户每次访问包含applet的网页时需要执行的代码放在其中。典型的操作是重新激活线程。 (3)void stop():覆盖这个方法,将用户每次离开包含applet网页时需要执行的代码放入其中。典型的操作时撤销线程。 (4)void destroy():覆盖这个方法,将用户退出浏览器时需要执行的代码放入其中。 7、Applet的HTML标记和属性: (1)code属性指出了类名,必须要包括.class扩展名。 (2)code、width和height属性是必需的。如果缺少任何一个,浏览器将不能加载applet。 8、Applet可以处理图像和音频。图像必须是GIF、PNG或JPEG格式。音频文件必须是AU、AIFF、WAV或MIDI格式。动画支持GIF,并且能显示动画效果。第11章 异常、日志、断言和调试 1、 如果一个方法有可能抛出多个已检查异常,那么就必须在方法的首部列出所有的异常类。每个异常类之间用逗号隔开。 2、 不需要声明Java的内部错误,即从Error继承的错误。任何程序代码都具有抛出那些异常的潜能,而我们没有对其没有任何控制能力。 3、 不应该声明从RuntimeException继承的那些未检查异常。 4、 如果在子类中覆盖了超类的一个方法,子类方法中声明的已检查异常不能超过超类方法中声明的异常范围(也就是说,子类方法中抛出的异常范围更加小,或者根本不抛出任何异常)。如果超类方法没有抛出任何已检查异常,子类也不能抛出任何已检查异常。 5、 在Java中,没有throws说明符的方法将不能抛出任何已检查异常。 6、 一旦方法抛出了异常,这个方法就不可能返回到调用者;如果catch子句抛出了一个异常,异常将被抛回这个方法的调用者。 7、 创建异常类时,定义的类应该包含两个构造器,一个是默认的构造器,另一个是带有详细描述信息的构造器(超类Throwable的toString方法将会打印出这些详细信息)。 8、 应该捕获那些知道如何处理的异常,而将那些不知道怎么处理的异常传递出去。如果想将异常传递出去,就必须在方法的首部添加一个throws说明符,以便告知调用者这个方法可能会抛出异常 9、 当finally子句包含return语句时,将会出现一种意想不到的结果。假设利用return语句从try语句块中退出。在方法返回前,finally子句的内容将被执行。如果finally子句中也有一个return语句,这个返回值将会覆盖原始的返回值。 10、堆栈跟踪(stack trace)是一个方法调用过程的列表,它包含了程序执行过程中方法调用的特定位置。 11、断言机制允许在测试期间向代码中插入一些检查语句。当代码发布时,这些插入的检测语句将会被自动地移走。在Java SE1.4中,Java语言引入了关键字assert。在默认情况下,断言被禁用。这个关键字有两种形式: (1)assert 条件; (2)assert 条件:表达式; 12、在Java语言中,给出了三种处理系统错误的机制: (1)抛出一个异常 (2)日志 (3)使用断言第12章 泛型程序设计 1、 一个泛型类就是具有一个或多个类型变量的类。 2、 泛型方法可以定义在普通类中,也可以定义在泛型类中。 3、 一个类型变量或通配符可以有多个限定,限定类型用“&”分隔,而逗号用来分隔类型变量。 4、 虚拟机没有泛型类型对象——所有对象都属于普通类。 5、 使用Java泛型时需要考虑的一些限制。大多数限制都是由类型檫除引起的: (1)不能用基本类型实例化类型参数; (2)运行时类型查询只适用于原始类型; (3)不能抛出也不能捕获泛型类实例; (4)参数化类型的数组不合法(不能声明参数化类型的数组); (5)不能实例化类型变量; (6)泛型类的静态上下文中类型变量无效(不能再静态域或方法中引用类型变量); (7)注意檫除后的冲突。第13章 集合 1、 集合类的基本接口是Collection接口。 2、 Map接口没有实现Collection接口! 3、Java集合中的具体集合: 4、在Java程序设计语言中,所有链表实际上都是双向链接的——即每个结点还存放着指向前驱结点的引用。 5、如果要查看链表中第n个元素,就必须从头开始,越过n-1个元素。没有捷径可走! 6、get()方法做了微小的优化:如果索引大于size()/2就从列表尾端开始搜索元素。 7、Vector类的所有方法都是同步的。 8、在Java中,散列表用链表数组实现。 9、将一个元素添加到树中要比添加到散列表中慢,但是,与将元素添加到数组或链表的正确位置上相比还是快很多的。 10、如果对同一个键两次调用put()方法,第二个值就会取代第一个值。 11、查看Map的键与值: for(Map.Entry<Integer,String> element:map.entrySet()){ int key = element.getKey(); String values = element.getValue(); System.out.println(key+"\t"+values); }第14章 多线程 1、 多进程与多线程的本质区别在于:每个进程拥有自己的一整套变量,而线程则共享数据。 2、 线程可以有如下6种状态: (1)New(新生) (2)Runnable(可运行) (3)Blocked(被阻塞) (4)Waiting(等待) (5)Timed waiting(计时等待) (6)Terminated(被终止) 3、线程因如下两个原因之一而被终止: (1)因为run方法正常退出而自然死亡; (2)因为一个没有捕获的异常终止了run方法二意外死亡。 4、在Java程序设计语言中,每一个线程有一个优先级。默认情况下,一个线程继承它的父线程的优先级。 5、守护线程的唯一用途是为其它线程提供服务。守护线程应该永远不去访问固有资源,如文件、数据库,因为它会在任何时候甚至在一个操作的中间发生中断。 6、默认情况下,创建的所有线程属于相同的线程组。 7、经验证明suspend方法会经常导致死锁。 8、Swing不是线程安全的。只有很少的Swing方法是线程安全的。 9、将线程与Swing一起使用时,必须遵循两个简单的原则: (1)如果一个动作需要花费很长时间,在一个独立的工作器线程中做这件事不要在事件分配线程中做。 (2)除了线程分配线程,不要在任何线程中接触Swing组件。 10、每一个Java应用程序都开始于主线程中的main方法。