rel="File-List" href="file:///C:%5CDOCUME%7E1%5C%E4%B8%B0%E5%9B%BD%E6%A0%8B%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"> rel="Edit-Time-Data" href="file:///C:%5CDOCUME%7E1%5C%E4%B8%B0%E5%9B%BD%E6%A0%8B%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_editdata.mso">
Introduction to Java Programming | |
1 | Java程序编译后,产生字节码(bytecode),字节码可以在任何装有java虚拟机(Java Virtual Machine,JVM)的计算机上运行。Java虚拟机是解释Java字节码的程序。 |
2 | 数值类型转换:当两个类型不同的运算对象进行二元运算时, ① 运算对象之一是double,结果转换为double ② 否则,之一为float,结果为float ③ 否则,之一为long,结果为long ④ 否则,转换为int 所以下列一段代码有错误 short i=1; i=i+1;//错误原因:int无法转换为short 可以改成i=(short)(i+1);或者i+=1; |
3 | Java运算符优先级
① 除了赋值运算符,所有双目运算符都是左结合的。 a- b+c-d等于((a-b)+c)-d,a=b+=c=5等于a=(b+=(c=5))
② &与&&,|与||的不同在于:&为无条件或,&&为条件或,即a&&b,如果a为false则不计算b,&不管a是否为false,都要计算b。 |
4 | If语句中,最好最后一个语句采用else而不是else if,不然解释器可能认为还没有结束。 public static int sign(int n) { if(n < 0) return 1; else if(n == 0) return 0; else if(n < 0) return -1; } error:This method must return a result of type int |
5 | 每当调用一个方法时,系统将参数、局部变量和系统寄存器存储在内存区域堆栈中(stack),后进先出的方式存储数据。当一个方法调用另一个方法时,调用者的空间不变,新开辟的空间保存新方法的调用。一个方法结束返回到调用者时,其相应的空间也被释放。 |
6 | 方法的参数传递过程中,无论形参如何改变,实参不受影响。形参是方法中具有自己存储空间的局部变量,局部变量再调用方法时分配的,当方法返回时就消失了。 |
7 | Java中可以使用赋值语句复制基本类型的变量,但是不能复制数组。将一个数组变量赋值给另一个数组变量,实际上是将一个数组的引用复制给另一个变量,使两个变量指向相同的内存地址。 如下例输出10 10 10 10 public static void main(String[] args) { // TODO Auto-generated method stub int[] arrayA = new int[4]; int[] arrayB = arrayA; change(arrayB);
for(int value:arrayA) { System.out.println(value); } } public static void change(int[] array) { for(int i = 0; i < array.length; i++) { array[i] = 10; } } |
8 | 数组复制的3种方法: ① 用循环语句复制数组的每一个元素 ② 用System类的静态方法arraycopy, public static void arraycopy(Object src,
int srcPos, Object dest, int destPos, int length) arraycopy没有给目标数组分配内存空间,复制前必须创建目标数组并给其分配内存空间。 ③ 用clone方法复制数组 |
9 | 给方法传递参数: ① 对于基本数据类型的参数,传递的是实参的值 ② 对于数组类型的参数,参数值是数组的引用,给方法传递的是这个引用 ③ 对于对象,结构等的参数,传递的也是引用 数组存储在堆(heap)的内存空间,堆用于动态内存分配,在堆中内存块可以按任意的顺序分配和释放。 |
10 | 对于排序,java.util.Array类提供了排序的方法,可以用于int,double,char,short,long和float型数组。对于已经排序好的数组,java.util.Array提供了binarySearch方法。 |
11 | 永久类: ① 类的所有数据是私有的并且没有修改器 ② 并且不含有返回引用非永久对象数据域的修改器和访问器。 |
12 | 如果让类的所有实例共享数据,采用静态变量(static variabl),静态变量存储在类的公用内存中。静态方法:不创建实例就可以调用静态方法。 |
13 | 类(inner class)特征: ① 内部类可以引用包含在他的外部类中的数据和方法,所以不必把外部类的引用传递给内部类的构造方法 ② 内部类只是用来支持其外部类的工作,编译后,名称如“外部类名称$内部类名称.class” ③ 内部类可以声明为public,protected或private,意义与用在类的其他成员相同 ④ 内部类可以声明为静态(static)类,可以使用外部类的类名来访问静态的内部类,静态内部类不能访问外部类的非静态成员。 ⑤ 可以在外部类中创建内部类的对象实例,也可以在另外的类中创建内部类的对象实例。如果内部类是非静态的,必须先创建外部类的实例,再使用下列语句来创建内部类的实例: 外部类.内部类 内部类对象名 = 外部类对象.new 内部类(); ⑥ 如果内部类是静态的,采用下列语法创建它的对象: 外部类.内部类 内部类对象名 = new 外部类.内部类();
下面例子有错: public class MyInnerClass { private int data; public void m(){ InnerClass instance = new InnerClass(); } //inner class static class InnerClass{//error,因为定义为静态内部类,不能访问外部类的 //非静态成员 public void mi(){ data++; m(); } } } |
14 | Static inner class 和 inner class的区别: ① static inner class 不能访问外部类的非静态成员 ② static inner class可以用外部类名来创建,不必须外部类的对象。可以用外部类的类名来访问静态内部类。 |
15 | String对象是永久的,内容不能改变。 String s = “Java”; S = “HTML”; 首先创建了内容为“Java”的String对象,并将其引用赋值给s。第二条是创建了一个内容为”HTML”的新的String对象,并将其引用赋给s,”Java”这个String对象还是存在的,只是不能再访问他。 如果两个String对象是通过快捷初始化用相同的字符串直接构建,JVM将他们存储在同一个对象中,如: String s = "Java"; String s1 = new String("Java"); String s2 = s1.intern(); String s3 = "Java"; System.out.println("s1 == s is "+(s1 == s)); System.out.println("s2 == s is "+(s2 == s)); System.out.println("s3 == s is "+(s3 == s)); 输出为: s1 == s is false s2 == s is true s3 == s is true |
16 | String s = new String("xyz");创建了几个String Object? 2个,"xyz "作为一个常量字符串首先被创建,它被保存在“串池”中。所谓串池,简单讲就是从程序运行开始,你创建的所有常量字符串被统一保存的地方。在串池中已经存在 "xyz "这个串的情况下,如果你需要一个内容相同的串,你不需要再次创建一个,而是直接用这个就可以,这样当然是为了节省空间。注意,一个字符串是无法被修改的,所以在程序的不同地方用不同变量引用同一个常量串没有任何危险,因为你只能读取它而不能修改它。 |
17 | 使用多个单个字符为定界符扫描一个字符串时,使用StringTokenizer类,如果用一个单词作为定界符,使用Scanner类。 |
18 | http://java.ccidnet.com/art/297/20060325/489133_1.html http://java.ccidnet.com/art/297/20060325/489133_2.html 前言: 在这里我要澄清一点:Nested class != inner class, inner class 是一种特殊的 Nested class.Bruce 大叔在thinking java 3rd中混肴了这两个概念。(汗,直到写此文时我才究正过来,还好我写得时候把 java language spec和 jvm spec 拿来参考) |
19 | 父类和子类的构造关系: 子类构造时,默认的会调用父类的默认无参构造方法,即相当于子类构造的第一句调用super(),这里的效果和显式调用是一样的。也可以在子类构造的第一句显式调用父类覆盖的构造方法。在任何情况下,构造一个类的实例时,会沿着继承链调用所有父类的构造方法(构造链)。 public class FacultyTest extends Employee{
/** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub new FacultyTest(); } public FacultyTest(){ super();//这里屏蔽super的效果是一样的 System.out.println("Faculty's no arg constructor is invoked"); } } class Employee { public Employee(){ System.out.println("Employee's no arg constructor is invoked"); } public Employee(String s){ System.out.println(s); } } 下面的例子是有错误的,因为类显式定义了构造方法,没有无参数构造方法,在子类构造中又没有显式的调用super(参数): public class FacultyTest extends Employee{
/** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub new FacultyTest(); } public FacultyTest(){ System.out.println("Faculty's no arg constructor is invoked"); } } class Employee { public Employee(String s){ System.out.println(s); } } 错误信息: Implicit super constructor Employee() is undefined. Must explicitly invoke another constructor |
20 | 调用父类的方法和方法覆盖: public class ReflectTest {
/** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub MyCylinder test = new MyCylinder(2.0,3.0); System.out.println(test.findArea()); MyCircle test1 = new MyCylinder(2.0,3.0); System.out.println(test1.findArea()); MyCircle test2 = new MyCircle(2.0); System.out.println(test2.findArea()); }
}
class MyCircle{ private double radius = 1.0; public MyCircle() { // TODO Auto-generated constructor stub System.out.println(" Invoke Circle without arg"); } public MyCircle(double radius){ this.radius = radius; System.out.println(" Invoke Circle with arg"); } public void setRadius(double radius){ this.radius = radius; } public double getRadius(){ return this.radius; } public double findArea(){ return Math.PI * radius * radius; } }
class MyCylinder extends MyCircle { private double length = 1.0; public MyCylinder() { // TODO Auto-generated constructor stub System.out.println("Invoke Cylinder without arg"); } public MyCylinder(double radius, double length){ super(radius); this.length = length; System.out.println("Invoke Cylinder with arg"); } public double getLength(){ return this.length; } public void setLength(double length){ this.length = length; } public double findArea(String s){ return (2 * super.findArea() + 2 * getRadius() * Math.PI * length); } } 输出为: Invoke Circle with arg Invoke Cylinder with arg 12.566370614359172 Invoke Circle with arg Invoke Cylinder with arg 12.566370614359172 Invoke Circle with arg 12.566370614359172
在子类(extended class)中重写父类的方法,必须要有相同的修饰符和方法名,形式参数名,方法重载需要有不同的形式参数,如果仅仅是返回值类型不同,不能作为方法重载。 注意:不能使用super.super.方法()来访问祖父类的方法,有语法错误。 class A{ method1(){} } class B extends A{ method1(){} } 则B的实例不能够访问A的method1方法,因为在B中method1方法被覆盖了。 注意:实例方法仅当可以被访问时才会被覆盖。私有方法不能在定义它的类外访问,所以不能被覆盖。如果子类的方法在父类中是私有的,则这两个方法完全没有关系。 注意:每个子类的实例都是父类的实例,反之不行。 |
21 | 多态的一个例子: public class PolyTest {
/** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub m(new GraduateStudent()); m(new Student()); m(new Person()); m(new Object()); Person test = new GraduateStudent(); Student test2 = (Student)test; m(test2); //test.finde(); error! if(test instanceof Student){ Student test3 = (Student)test; test3.finde(); } } static public void m(Object x){ System.out.println(x.toString()); } } class GraduateStudent extends Student { public String toString(){ return "GraduateStudent"; } public void finde(){ System.out.println("hoho"); } } class Student extends Person{ public String toString(){ return "Student"; } } class Person{ public String toString(){ return "Person"; } } 输出: GraduateStudent Student Person java.lang.Object@61de33 GraduateStudent Hoho
为父类对象设计的代码都可以引用于子类,这个特征成为多态(polymorphism)。 动态绑定机制:类c1->c2->…->cn,c1为父类,c2为子类,o为cn的实例,则o调用一个方法p,依次在cn,cn-1,…,c1中查找p的实现,直到找到为止。一旦找到一个实现,停止查找并调用这个第一次找到的实现。 向上转换:将一个子类的实例转换为一个父类的实例总是可行的 向下转换:必须使用显式转换,为是转换成功,转换的对象必须是子类的一个实例。在转换时确保该对象是另一个对象的实例,用instanceof来判断。 |
22 | 隐藏数据域和静态方法(static): 可以覆盖一个实例方法,但是不能覆盖一个数据域(不管是实例或者静态的)和静态的方法。子类声明的数据域或者静态方法和父类中的相同,父类的将被隐藏,但是没有被覆盖。在子类中还可以使用super来调用父类的隐藏的数据或者静态方法。 |
23 | finalize方法: 由于java中没有显式的释放资源和内存的函数,存在gabbage collection的机制,当资源变成垃圾时,finalize会被该对象的垃圾回收gc调用。子类可以覆盖finalize方法,释放系统资源或者进行其他清洁工作。 Protected void finalize() throws Throwable |
24 | Clone方法,创建一个新的对象,并使得其和就对象内容方法相同 newObject = oldObject.clone(); 不是所有的对象都可以被克隆,要成为一个可被克隆的对象,它的类必须实现java.lang.Cloneable接口。 数组的clone:int [] B = (int[])A.clone(); |
25 | Collection 和 Collections的区别 Collection是个java.util下的接口,它是处理对象集合的根接口。 Collections是个java.util下的类,它包含管理集合与图、创建同步集合类、创建只读集合类等静态方法。 |
26 | http://dev.youkuaiyun.com/article/85006.shtm 正则表达式: 正则表达式用来指定字符串模式。当你需要定位匹配某种模式的字符串时就可以使用正则表达式。例如,我们下面的一个例程就是在一个HTML文件中通过查找字符串模式<a href="...">来定位所有的超链接。
例如,字符串cab匹配[a-z]*ab,但不匹配[a-z]*+ab。第一种情况下,[a-z]*只匹配字符c,因此字符ab正好与模式的剩余部分匹配。但是贪婪版本[a-z]*+就与字符cab匹配,模式的剩余部分ab就匹配失败(,这样总体也就匹配失败)。
语法 解释 字符 /0n 八进制0n代表的字符(0<=n<=7) /0nn 八进制0nn代表的字符(0<=n<=7) /0mnn 八进制0mnn代表的字符(0<=m<=3,0<=n<=7) /xnn 十六进制 0xnn所代表的字符 /uhhhh 十六进制 0xhhhh所代表的字符 /t, /n, /r, /f, /a, /e 控制字符,依次是制表符,换行符,回车符,换页符,报警符和转义符 字符类 预定义字符类 边界匹配符 量词 量词后缀 集合操作 分组 转义
Pattern pattern = Pattern.compile(patternString); Matcher matcher = pattern.matcher(input); if (matcher.matches()) . . .
Lower 小写的ASII字符[a-z]
Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE + Pattern.UNICODE_CASE);
CASE_INSENSITIVE:匹配字符时与大小写无关,该标志默认只考虑US ASCII字符。 UNICODE_CASE:当与CASE_INSENSITIVE结合时,使用Unicode字母匹配 MULTILINE:^和$匹配一行的开始和结尾,而不是整个输入 UNIX_LINES: 当在多行模式下匹配^和$时,只将'/n'看作行终止符 DOTALL: 当使用此标志时,.符号匹配包括行终止符在内的所有字符 CANON_EQ: 考虑Unicode字符的规范等价 如果正则表达式包含分组,Matcher对象能够揭示分组边界。方法 int start(int groupIndex) int end(int groupIndex) 返回某个特殊分组的起始索引和结尾后索引(past-the-end index )。 分组索引 起始 结束 字符串 0 0 7 11;59am while (matcher.find()) { int start = matcher.start(); int end = matcher.end(); String match = input.substring(start, end); . . . }
import java.io.*; import java.net.*; import java.util.regex.*;
public class RefMatch { public static void main(String[] args) { try { // get URL string from command line or use default String urlString; if (args.length > 0) urlString = args[0]; else urlString = "http://bbs.ustc.edu.cn/cgi/bbsall";
// open reader for URL InputStreamReader in = new InputStreamReader(new URL(urlString).openStream());
// read contents into string buffer StringBuilder input = new StringBuilder(); int ch; while ((ch = in.read()) != -1) input.append((char) ch);
// search for all occurrences of pattern //String patternString = //"<a//s+href//s*=//s*(/"[^/"]*/"|[^//s>])//s*>"; String patternString = "<a//s+href//s*=//s*/"[^/"]*/"[^>]*>"; Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(input);
while (matcher.find()) { int start = matcher.start(); int end = matcher.end(); String match = input.substring(start, end); System.out.println(match); } } catch (IOException e) { e.printStackTrace(); } catch (PatternSyntaxException e) { e.printStackTrace(); } } } Pattern pattern = Pattern.compile("[0-9]+"); Matcher matcher = pattern.matcher(input); String output = matcher.replaceAll("#"); 替换字符串可以包含模式中的分组引用:$n被第n个分组替换。替换文本中出现$时,使用/$来包含它。 Pattern pattern = Pattern.compile("//s*//p{Punct}//s*"); String[] tokens = pattern.split(input);
java.util.regex.Pattern 1.4 方法 类 java.util.regex.Matcher 1.4 方法 boolean matches() |
27 | Java的中文帮助文档: http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/overview-summary.html |
28 | Hashtable,Hashmap |