1、C+程序员程序员Java速成速成北京大学信息学院 郭炜一、程序结构1.一个Java 程序可以由多个.java文件组成,必须有且只有一个类,含有 public static void main(String args)成员函数,Java程序从这个函数开始执行public class HelloWorld public static void main(String args)System.out.println(Hello,World);一、程序结构2.程序存在.java文件中。一个.java文件里可以有多个class,但是只能有一个class是public的。.java文件里 可以没有类是pu
2、blic的。包含main的那个类也可以不是public的。3.java文件里如果有public的class,那么文件名必须和该类名一致(大小写相关)。如果没有public类,那么文件名也必须和其中某个类(随便哪个都行)相同。4.Java程序大小写相关,甚至文件名都是大小写相关的。5.java文件的编码必须是ANSI的.6.Java程序中的每个类,经过编译后会变成一个.class文件,文件名和类名相同。7.a.java中如果用到了文件b.java中的类,那么不做特殊处理的话,程序运行时,应确保a.class应该和 b.class在同一个文件夹下。8.Java没有全局变量和全局函数。所有东西都写在
3、 class里面。一、程序结构1.java有boolean数据类型,没有bool类型。boolean类型的取值是true或false。boolean和int类型不能互相转换。条件表达式必须是boolean类型的,不能把0当false,非0当true2.有byte数据类型,byte类型的变量占一个字节,取值是-128 127。3.float常量后面要加 f 或 F,如:float y=0.3f,x=1.3e-4f;二、数据类型4.char类型的变量可以是Unicode字符表中的字符,包括可以是汉字,如:char c=好;char类型变量里,存放的是字符在 unicode编码里的序号。Unicod
4、e编码一共65535个字符。字母、数字和普通标点符号在unicode里的编号正好和其ASCII码相等。不能认为char类型的变量占一个字节。二、数据类型5.long类型的变量占8个字节。long类型的常量后面要跟L或l,如:long a=0 xffffffffffaL;6.将精度高的数值赋值给精度低的变量时,必须要进行强制类型转换,不过char类型和int类型可以互相赋值,只要赋给char类型的int值不超过65535;二、数据类型public class HelloWorld public static void main(String args)float y=0.3f,x=1.3e-4f
5、;char c=好;long a=0 xffffffffffL;System.out.println(c);System.out.println(a);System.out.println(int)好);System.out.println(char)22900);System.out.println(int)a);/int n=3.232;/wrongchar c1=65535;/ok/char c2=65536;/wrong输出:好109951162777522909奴971.成员变量被称为“属性”,成员函数被称为“方法2.Java中没有指针,但Java对象本质上只是相当于C+中的指针,必
6、须通过new运算符创建后才能被使用。class Test int n;public class HelloWorld public static void main(String args)Test t;/本质上相当于C+的 Test*t;t.n=100;/错,t还没有初始化,对象不存在三、对象的概念正确的写法:class Test int n;public class HelloWorld public static void main(String args)Test t;t=new Test();t.n=100;三、对象的概念3.Java 中对象用new创建后,不需要delete。Jav
7、a虚拟机有垃圾回收机制,定期自动回收没用的对象。4.对象间互相赋值会使得两个对象指向(或说是引用)相同的地方三、对象的概念class A int i;public class HelloWorld public static void main(String args)A a1=new A(),a2=new A();a1.i=10;a2.i=20;a1=a2;a1.i=30;System.out.println(a2.i);输出:301.Java 中的数组都是对象,有许多属性和方法。比如length属性表示数组元素个数。2.一维数组的两种定义方式(无区别):类型 数组名 ;类型 数组名;不能在
8、 中指定元素个数 四、数组3.数组定义后并不占有内存,也必须用new运算符创建后才能使用。创建时指定元素个数。float gpa;gpa=new float300;/300个元素也可以定义时直接初始化:float gpa =new float4;int a =1,2,3,4,5;System.out.println(a.length);/输出5四、数组一维对象数组初始化:class Student int n;Student(int v)n=v;public class HelloWorld public static void main(String args)Student aStuden
9、t=new Student(3),new Student(2),new Student(4);四、数组数组new后,每个元素都是null,每个元素都需要new后才能使用class Demo int n;void ArrayDemo()Demo a=new Demo10;a1.n=5;/上面会引发 java.lang.NullPointerException 错误a1=new Demo();a1.n=5;四、数组4.二维数组的每一行都可以分别初始化,而且每一行的元素个数可以不一样。二维数组的length属性代表其行数,也就是其中一维数组的个数。四、数组int a =1,2,3,2,3,4,5;S
10、ystem.out.println(a.length);/输出 3System.out.println(a0.length);/输出 3System.out.println(a1.length);/输出 25.二维数组的其他初始化方式:四、数组public class HelloWorld public static void main(String args)int b,c;b=new int45;c=new int4;c0=new int3;c1=new int100;System.out.println(c.length);/输出 4System.out.println(c0.lengt
11、h);/输出 3 System.out.println(c1.length);/输出 100System.out.println(c2.length);/运行时导致java.lang.NullPointerException 错误 6.数组是对象,本质是指针。同类型数组之间可以互相赋值。import java.util.Arrays;/类似于C+的#incudepublic class HelloWorld public static void main(String args)char a =h,e,k;char b =1,2,3,4;a=b;/a 和 b 指向(或称引用)同一个数组,a原来
12、指向的数组被垃圾回收System.out.println(a.length);a0=a;/b0也变成 aString s=Arrays.toString(b);System.out.println(s);/Arrays是Java标准类,能将数组转换成字符串四、数组输出:4a,2,3,47.Arrays是Java标准类,能将数组转换成字符串import java.util.Arrays;/类似于C+的#incudepublic class HelloWorld public static void main(String args)int a =12,34,29;System.out.print
13、ln(Arrays.toString(a);四、数组输出:12,34,298.关于char数组char类型的的数组可以直接用println输出其全部内容char a=a,b,c;System.out.println(a);/输出 abcchar类型的数组不能如下初始化:char a =this;四、数组9.拷贝数组System.arraycopy(srcArray,int idx1,destArray,int idx2,int len)将srcArray从下标idx1开始的len个元素拷贝到destArray从下标idx2开始的地方。destArray必须足够大。Arrays.copyOfRa
14、nge(someArray,int from,int to)将 someArray从from开始到to-1的元素复制到一个新数组中并且返回。四、数组import java.util.Arrays;public class HelloWorld public static void main(String args)int a=1,2,3,4;int b=5,6,7,8,9;System.arraycopy(b,0,a,1,2);System.out.println(Arrays.toString(a);int c=Arrays.copyOf(b,3);System.out.println(Ar
15、rays.toString(c);int d=Arrays.copyOfRange(b,1,4);System.out.println(Arrays.toString(d);int e=Arrays.copyOfRange(b,1,9);System.out.println(Arrays.toString(e);四、数组1,5,6,45,6,76,7,86,7,8,9,0,0,0,0输出:四、数组10.遍历数组:除了和C+一样的遍历方式外,还有如下方式public class HelloWorld public static void main(String args)int a=1,2,3,
16、4;int n=0;for(int k:a)n+=k;System.out.println(n);char b=a,b,c;for(char ch:b)System.out.print(ch);10abc输出:import java.util.Arrays;enum Season Spring,Summer,Autum,winter public class HelloWorld public static void main(String args)Season x;x=Season.Spring;System.out.println(x);输出:Spring五、枚举类型六、类1.所有成员函
17、数的函数体都写在 class./此处不需要;里面,不能拿出来写。2.成员变量可以是本类的对象(因对象本质是指针)class LinklistNode int n;LinklistNode next;六、类3.静态属性称为“类变量”,非静态属性称为“实例变量”。静态方法称为“类方法”,非静态方法称为“实例方法”。4.同样存在“this指针”,当然在Java里不叫指针。在类的方法内可以通过“this.成员名”的方式访问成员。总之,C+中的“-”和“:”在Java里都是“.”六、类5.写类定义时,可以对属性进行初始化。class Test int n=4;double f=1.3f;public c
18、lass HelloWorld public static void main(String args)Test t=new Test();System.out.println(t.n);System.out.println(t.f);41.2999999523162842输出:六、类7.构造方法没有初始化列表。要调用基类的构造方法,就写 super(.);8.类派生使用关键字 extends六、类class A int n;A(int v)n=v;class B extends Aint v;B(int n)super(n);/没有此句,编译不过。public class HelloWorl
19、d public static void main(String args)B b=new B(4);System.out.println(b.n);六、类9.封闭类的构造函数中不需要交代如何初始化成员对象。class A int n;A(int v)n=v;class B int v;A a;B(int n)public class HelloWorld public static void main(String args)B b=new B(4);为什么?七、函数参数传递Java中的函数,参数都是传值的,没有传引用的。如果参数是对象,则效果和C+中参数是指针的情况一样。class A i
20、nt i;A(int v)i=v;class Functions static void Swap1(A a1,A a2)int tmp=a1.i;a1.i=a2.i;a2.i=tmp;static void Swap2(A a1,A a2)A tmp=a1;a1=a2;a2=tmp;public class HelloWorld public static void main(String args)A a=new A(5),b=new A(10);Functions.Swap1(a,b);System.out.printf(%d,%dn,a.i,b.i);Functions.Swap2(a
21、,b);System.out.printf(%d,%dn,a.i,b.i);输出:10,510,5八、包和import语句为避免不同的.java文件中出现名字相同的类导致冲突,Java引入了包的概念。类可以分属不同的包,不同包里的类可以重名。使用“包名.类名”形式就能避免类的命名冲突。类似于C+的“名字空间:类名”用 package语句作为.java文件的第一条语句,指明该文件所属的包名。如果没有package语句,该文件中的类就都属于“无名包”(或叫“默认包”default package)。八、包和import语句包名可以是一个标识符,也可以是多个标识符用.连接,如:package pku
22、;package pku.eecs.cs;八、包和import语句程序运行时,如果包含 main 的那个类的.class文件在当前文件夹下,则:如果文件里指定包名是 pku,那么该文件编译出来的.class 文件就应该位于当前文件夹下的 pku子文件夹下如果文件里指定包名是 pku.eecs.cs,那么该文件编译出来的.class 文件就应该位于当前文件夹下的 pkueecscs子文件夹下总之,包名里的一个标识符,就代表一个文件夹。也可以认为包就是一个文件夹。八、包和import语句在eclipse中,鼠标右键点击工程名(或已有的包名),在弹出的菜单上选 new-package 就可以新建一个
23、package在eclips工程里,编译出来的.class文件都放在工程的 bin文件夹下,源程序都放在 src文件夹下.源程序文件的存放位置与包名的关系,和.class文件存放位置与包名的关系一样。八、包和import语句多包程序的例子-有eclipes工程 example1八、包和import语句example1有以下文件:example1srcHelloWorld.javapublic class HelloWorld public static void main(String args)gw1.PackageTest p=new gw1.PackageTest();p.PrintIn
24、fo();gw1.PackageTest2 p2=new gw1.PackageTest2();p2.PrintInfo();gw2.subgw1.SubPackageTest sp=new gw2.subgw1.SubPackageTest();sp.PrintInfo();八、包和import语句example1srcgw1 PackageTest.javapackage gw1;public class PackageTest public void PrintInfo()System.out.println(this is PackageTest Obj);八、包和import语句ex
25、ample1srcgw1 PackageTest2.javapackage gw1;public class PackageTest2 public void PrintInfo()System.out.println(this is PackageTest2 Obj);八、包和import语句example1srcgw2subgw1SubPackageTest.javapackage gw2.subgw1;public class SubPackageTest public void PrintInfo()System.out.println(This is SubPackageTest O
26、bject);Example1程序输出结果:this is PackageTest Objthis is PackageTest2 ObjThis is SubPackageTest Object八、包和import语句用import语句引入包,可以省去在类前面写包名import gw1.*;/gw1里面的类,都不用写包名了import gw2.subgw1.*;/gw1.subgw1里面的类,都不用写包名了public class HelloWorld public static void main(String args)PackageTest p=new PackageTest();p.
27、PrintInfo();PackageTest2 p2=new PackageTest2();p2.PrintInfo();SubPackageTest sp=new SubPackageTest();sp.PrintInfo();八、包和import语句 import语句也可以只引入一个类:import gw1.PackageTest;import gw2.subgw1.*;public class HelloWorld public static void main(String args)PackageTest p=new PackageTest();p.PrintInfo();gw1.
28、PackageTest2 p2=new gw1.PackageTest2();p2.PrintInfo();SubPackageTest sp=new SubPackageTest();sp.PrintInfo();八、包和import语句一个包对应于一个文件夹,但不包括该文件夹下的子文件夹。例如:import gw2.*;使得 gw2文件夹下的类被import进来,但是gw2subgw1文件夹下的类,并没有被import进来。要import它们,还是需要写:import gw2.subgw1.*;九、类的可使用范围 1.定义类时,前面可以加public关键字,也可以不加。加了,称为“公有类”
29、。同一个包里的类,不论是否在同一个.java文件中,不论是否是public,都可以互相使用。2.只能使用其他包里的 public类,不能使用其他包里的非 public类。十、类成员的可访问范围 1.类的成员,前面可以加 public(公有成员),private(私有成员)或protected(保护成员)。不加这三个标识符,并不缺省为私有,而是称为“友好成员”。2.一个类,可以访问同包类对象的公有、友好和保护成员,不可以访问同包类的私有成员3.一个类,可以访问异包类对象的公有成员,不能访问异包类对象的保护、私有和友好成员十、类成员的可访问范围 4.子类不能访问父类的私有成员。5.友好成员和保护成
30、员的区别是:与父类不在同一包中的子类,可以访问父类的保护成员,不能访问父类的友好成员。十、类成员的可访问范围(示例程序)package gw1;public class PackageTest public void PrintInfo()/友好方法System.out.println(this is PackageTest Obj);void FriendFunc()System.out.println(in FriendFunc);private void PrivateFunc()System.out.println(in PrivateFunc);protected void Prot
31、ectedFunc()System.out.println(in ProtectedFunc);example1srcgw1 PackageTest.java十、类成员的可访问范围(示例程序)package gw1;public class PackageTest2 public void PrintInfo()System.out.println(this is PackageTest2 Obj);PackageTest t=new PackageTest();t.FriendFunc();/ok,可访问同包类对象的友好成员t.PrivateFunc();/错,不可访问同包类对象私有成员t.
32、ProtectedFunc();/ok,可访问同包类对象保护成员t.PrintInfo();example1srcgw1 PackageTest2.java十、类成员的可访问范围(示例程序)import gw1.*;import gw2.subgw1.*;public class HelloWorld public static void main(String args)PackageTest p=new PackageTest();p.PrintInfo();/ok,可以访问异包类对象的公有成员 p.FriendFunc();/wrong,不可访问异包类对象的友好成员p.PrivateFu
33、nc();/wrong,不可访问异包类对象的私有成员p.ProtectedFunc();/wrong,不可访问异包类对象的保护成员example1srcHelloWorld.java十、类成员的可访问范围(示例程序)class Derived extends PackageTest void Test()PackageTest p=new PackageTest();p.ProtectedFunc();/错,不可访问异包对象的保护成员p.FriendFunc();/wrong,不可访问异包对象的友好成员ProtectedFunc();/ok,可以调用异包基类的保护方法PrivateFunc()
34、;/wrong,不能调用基类私有方法 FriendFunc();/wrong,不能调用异包基类的友好方法 example1srcHelloWorld.java十一、super 关键字 用“super.成员名”来访问基类的成员;在构造方法中用“super(.)”调用基类构造方法如果派生类的构造方法没有调用基类的构造方法,那么等效于用“super();”调用基类的无参构造方法class A int v;A(int n)v=n;void Init()System.out.println(A.Init);class B extends A B(int n)super(n);void Init()sup
35、er.Init();System.out.println(B.Init);public class HelloWorld public static void main(String args)B b=new B(5);b.Init();十一、super 关键字输出:A.InitB.Init1.假设有基类方法Function1,返回值类型是A,派生类中可以写同名同参数表的Funciton1,返回值类型是可以是A,也可以是 A的派生类。2.重写基类的方法时,不能缩小方法的可访问范围。比如基类的Function1是public 的,那么派生类中重写的同名同参数表的 Function1,就不能是友好
36、、保护或私有的。十二、派生类重写(覆盖)基类方法1.final 关键字可以修饰类、成员变量和方法中的局部变量2.final关键字修饰的类,不允许有派生类final class A A 不能有派生类。Java 中的String类,就是final的3.final修饰成员变量和局部变量时,作用相当于C+的const,即常量4.final成员变量和局部变量必须在声明的时候初始化。十三、final 关键字5.final成员变量必须在声明时初始化或在构造函数中初始化,初始化后,其值不可改变。以下初始化方式均可:class A final int v=4;A(int n)或:class A final in
37、t v;A(int n)v=n;十三、final 关键字6.final局部变量也可以不初始化,但是赋值或创建一次后,就不能修改其值。7.一个对象是final的,其含义并不是其成员变量的值不能被修改,而是它不能再指向别的对象,类似于C+的 类型*const 指针名;如int *const p;十三、final 关键字public class HelloWorld public static void main(String args)final A a;final int n;n=4;a=new A(10);System.out.printf(%d,%dn,n,a.v);n=9;/wronga=
38、new A(20);/wronga.v=100;/wrong;a.k=100;/ok;System.out.println(a.k);十三、final 关键字(例程)class A final int v;int k;A(int n)v=n;去掉出错的语句后,输出:4,101001.abstract 类相当于C+中的抽象类,abstract方法相当于C+的纯虚函数。只有abstract类才能有abstract方法。和C+不同之处在于,abstract类中可以没有abstract方法。abstract class A abstract void func();/不能写函数体 2.abstract
39、类不能用new运算符创建对象。十四、abstract 类和abstract方法1.接口(interface)是Java中的重要概念。接口和类有点像,但是其所有的成员变量都是public且final的(不写public和final也有一样),所有的成员函数都是abstract 且public的(不写public和abstract 也有一样)。例如:interface A int n=5;void Func(int a,int b);int PrintInfo();可以定义接口变量,如 :A a;但是,不能用new运算符来创建“接口对象”。十五、接口2.接口可以派生出子接口:interface A
40、 int n=5;void Func(int a,int b);int PrintInfo();interface B extends A double f=3.0;int Count();十五、接口3.接口可以派生出类。从接口派生类,用implements关键字,也称为类“实现”了某个接口:interface A int n=5;void Func(int a,int b);int PrintInfo();class C implements A double c;int SomeFunc()return 0;public void Func(int a,int b)public int P
41、rintInfo()return 1;十五、接口实现了接口的类,一定要对接口中的全部方法都重写,写成public的,要写出函数体。若有接口的方法没有被重写,则这个类就必须是abstract 的。4.可以让接口变量指向一个new出来的实现了该接口的类的对象:interface B int v=6;void FuncB();class E implements B public void FuncB()System.out.println(in B.FuncB);public class HelloWorld public static void main(String args)B b=new
42、E();b.FuncB();十五、接口输出:in B.FuncB5.接口也可以用public来修饰,称为“公有接口”。public 接口可以被任何类实现,非 public接口仅可以被同一个包中的类实现。public interface A 十五、接口Java中没有多继承。一个类最多只能有一个基类。但是一个类可以在继承一个基类的同时,还实现多个接口(也可以只实现多个接口而不继承任何类)。十六、“多继承”interface A int n=5;void Func(int a,int b);int PrintInfo();interface B int v=6;void FuncB();class
43、C class D extends C implements A,B public void Func(int a,int b)public int PrintInfo()return 0;public void FuncB()1.Java中的方法,除了类方法(静态成员函数)外,都可以认为相当于是C+中的虚函数。十七、多态2.Java中多态的规则如下:1)通过基类对象,调用基类和派生类都有的同名同参数表的方法时,是多态。该基类对象如果指向的确是基类对象,那么指向的就是基类的方法,如果指向的是派生类对象,那么执行的就是派生类的方法。2)通过接口变量,调用接口和实现了该接口的类都有的同名同参数表的
44、方法时,是多态。被执行的是类的方法。接口存在的目的,就是为了实现多态十七、多态(例程)interface IA int n=5;void FuncIA();interface IB void FuncIB();class A void FuncA()System.out.println(in A.FuncA);class B extends A implements IA,IBvoid FuncA()System.out.println(in B.FuncA);public void FuncIA()System.out.println(in B.FuncIA);public void Fun
45、cIB()System.out.println(in B.FuncIB);class C extends Bvoid FuncA()System.out.println(in C.FuncA);public void FuncIA()System.out.println(in C.FuncIA);public class HelloWorld public static void main(String args)A a;IA ia;IB ib;a=new A();a.FuncA();a=new B();a.FuncA();a=new C();a.FuncA();ia=new B();ia.F
46、uncIA();ia=new C();ia.FuncIA();ib=new B();ib.FuncIB();ib=new C();ib.FuncIB();输出:in A.FuncAin B.FuncAIn C.FuncAin B.FuncIAin C.FuncIAin B.FuncIBin B.FuncIB十八、字符串1.String类:用来表示字符串String s1,s2;s1=hello;s2=hello;System.out.println(s1=s2);s2=new String(hello);System.out.println(s1=s2);输出:truefalse十八、字符串1
47、.String类:用来表示字符串String s=new String(hello);System.out.println(s.equals(hello);System.out.println(s=Hello);输出:truefalse十八、字符串1.String类:用来表示字符串int x;String s=123456;x=Integer.parseInt(s);System.out.println(x);String str=String.valueOf(1233.223);System.out.println(str);输出:1234561233.223十八、字符串2.字符串和字节数组
48、byte d =abc你我他.getBytes();System.out.println(d.length);String s=new String(d,3,2);System.out.println(s);s=new String(d);System.out.println(s);出:9你abc你我他十八、字符串3.正则表达式String regex=1-90-9*.?0-9*;/?代表出现0次或一次String str1=12r34a5;String str2=123.45908;if(str1.matches(regex)System.out.println(str1+是数字);else
49、 System.out.println(str1+不是数字);String result=str1.replaceAll(D+,);/D代表任意非数字字符,+代表出现一次或多次System.out.println(result);System.out.println(str2.matches(regex);输出:12r34a5不是数字12345true十八、字符串3.正则表达式String regex=sdpPunct+;String sentence=This,is890 whatt word:me;String words=sentence.split(regex);for(int i=0
50、;i words.length;+i)System.out.println(wordsi);输出:Thisiswhattwordme十八、字符串4.StringBuffer类 String字符串不能修改,StringBuffer可以StringBuffer str=new StringBuffer(123);str.append(456);System.out.println(str);char c=str.charAt(2);System.out.println(c);str.setCharAt(0,X);System.out.println(str);str.insert(2,abc);S