JAVA语言学习笔记(一)

1 一切都是对象

JAVA中所有代码都必须写在类里面。

方法名和参数列表(它们合起来被称为"方法签名")唯一地标识出某个方法。联想多态。

基本数据类型的"局部变量"相对于类的数据成员不会自动初始化,但会在编译时报错误。

面向对象的程序设计通常可简单的归为"向对象发送消息"。

JAVA中,除了基本数据类型,其它对象传递的是引用。

static域或方法,有特定的存储空间和可以直接用类直接调用(static字段对每个类来说都只有一份存储空间,而非static字段则是对每个对象有一个存储空间)。

2 操作符

观察一下代码,猜测输出的结果。

 1 class Tank {
 2     int level;
 3 }
 4 
 5 public class Think {
 6     public static void main(String[] args) {
 7         Tank t1 = new Tank();
 8         Tank t2 = new Tank();
 9         t1.level = 9;
10         t2.level = 47;
11         System.out
12                 .println("1: t1.level:" + t1.level + ", t2.level:" + t2.level);
13         t1 = t2;
14         System.out
15                 .println("2: t1.level:" + t1.level + ", t2.level:" + t2.level);
16         t1.level = 27;
17         System.out
18                 .println("3: t1.level:" + t1.level + ", t2.level:" + t2.level);
19     }
20 }

重点在13行,内部做了什么?

结果如下所示:

 equals和==号的运用,特别注意String类的特点

 1 class Value{
 2     
 3     String i;
 4 }
 5 public class EqualsMethods {
 6    public static void main(String[] args){
 7        Value v1 = new Value();
 8        Value v2 = new Value();
 9        v1.i = v2.i = "10"; //"10"是一个字符串常量,存储在常量区
10        
11        System.out.println(v1.equals(v2)); //false
12        System.out.println(v1.i.equals(v2.i)); //true
13        System.out.println(v1.i == v2.i); //true
14        
15    }
16 }

String类打印。 观察下面代码的第9行程序和注释的内容。也可以是(观察下面代码,判断是否发生错误?编译错误还是运行时错误?那类错误?)

 1 package thinkJava;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 public class InfiniteRecursion {
 7    
 8     public String toString(){
 9         return "InfiniteRecursion address: " + super.toString() + "\n"; //this ---> super.toString()
10     }
11     public static void main(String[] args){
12         List<InfiniteRecursion> v = new ArrayList<InfiniteRecursion>();
13         for(int i = 0; i < 10; i++){
14             v.add(new InfiniteRecursion());
15         }
16         System.out.println(v);
17     }
18 }
19 //如果你真的想打印出对象的内存地址,而是应该调用Object.toString()方法。
20 //这才是负责此任务的方法。所以。你不该用this,而是应该调用super.toString()方法。

如果用this方法,则发生递归死循环,很快给出运行时错误--

正确的做法是用父类的super.toString()方法。

 

 3 接口

抽象类,枚举、继承、类型、多态、循环、import方式

 

 1 package thinkJava;
 2 
 3 import testzd.Note; //testzd package中的Note.java文件
 4 
 5 abstract class Instrument {
 6     private int i;
 7 
 8     public abstract void play(Note n);
 9 
10     public String what() {
11         return "Instrument";
12     }
13 
14     public abstract void adjust();
15 
16 }
17 
18    // 继承抽象类,抽象方法一定要实现。如果不实现父类中的抽象方法,则子类必须也是抽象类,否则编译通不过。
19 class Wind extends Instrument {
20     public void play(Note n) {
21         System.out.println("Wind.pay() " + n);
22     }
23 
24     public String what() {
25         return "wind";
26     }
27 
28     public void adjust() {
29     };
30 }
31 
32 class Percussion extends Instrument {
33     public void play(Note n) {
34         System.out.println("Percussion.pay() " + n);
35     }
36 
37     public String what() {
38         return "Percussion";
39     }
40 
41     public void adjust() {
42     }
43 }
44 
45 class Stringed extends Instrument {
46     public void play(Note n) {
47         System.out.println("Stringed.play() " + n);
48     }
49 
50     public String what() {
51         return "Stringed";
52     }
53 
54     public void adjust() {
55     }
56 }
57 
58 class Brass extends Wind {
59     public void play(Note n) {
60         System.out.println("Brass.play() " + n);
61     }
62 
63     public void adjust() {
64         System.out.println("Brass.adjust()");
65     }
66 }
67 
68 class Woodwind extends Wind {
69     public void play(Note n) {
70         System.out.println("Woodwind.play() " + n);
71     }
72 
73     public String what() {
74         return "Woodwind";
75     }
76 }
77 
78 public class Music4 {
79 
80     static void tune(Instrument i) {
81         i.play(Note.MIDDLE_C);
82         i.play(Note.C_SHARP);
83         i.play(Note.B_FLAT);
84     }
85 
86     static void tuneAll(Instrument[] e) {
87         for (Instrument i : e) {      //遍历的方式
88             tune(i);
89         }
90     }
91 
92     public static void main(String[] args) {
93         Instrument[] orchestra = { new Wind(), new Percussion(),
94                 new Stringed(), new Brass(), new Woodwind() };  //Instrument 类型的,但是放进了好多子类型的。父类是抽象的,不能实例化。保证安全。
95         tuneAll(orchestra);
96     }
97 
98 }
99 //猜测下输出的结果,以及为什么这么繁琐的搞这么多的类?
View Code

 

 

 

testzd package中的Note.java文件如下所示
package testzd;

public enum Note {
     MIDDLE_C, C_SHARP, B_FLAT; // Etc.
}

运行的结果是:

abstract 修饰的类中可以没有抽象方法,即所有的方法全部都有实现体。但是依旧不能为抽象类定义对象。

interface关键字使抽象的概念更向前迈进了一部。interface是一个完全抽象的类。

1 interface中可以有字段和方法

2 字段隐式地是static 和final的

3 方法隐式地是public的

如下是一个接口的定义

 

1 interface Inst {
2     int VALUE = 5; // static & final
3 
4     // cannot have method definitions
5     void play(Note n); // Automaticaly public
6 
7     void adjust();
8 }

 

foreach迭代,可变参数列表

 1 class A{}
 2 public class TestObject{
 3     static void printArray(Object...args){
 4         for(Object obj:args){
 5             System.out.print(obj + " ");
 6         }
 7         System.out.println();
 8     }
 9     public static void main(String[] args){
10         
11         printArray(new Integer(47), new Float(12.3F), new Double(23.45));
12         printArray(47, 3.14F, 11.11);
13         printArray(new A(), new A(), new A());
14         printArray((Object[])new Integer[]{1, 2, 3, 4});
15         printArray(); //Empty list is Ok.
16         
17     }
18 }
可变参数列表

输出结果

1 47 12.3 23.45 
2 47 3.14 11.11 
3 thinkJava.A@1d1acd3 thinkJava.A@a981ca thinkJava.A@8814e9 
4 1 2 3 4 
结果

 

4 构造器与重载

默认构造器只有在没有明确创造构造器时候才会起作用。

下述代码,充分表明了this关键的作用和特点。

1 只可以用this关键字在构造器里调用其它构造器。

2 构造器的调用必须在语句的第一位置。

 

 1 package thinkJava;
 2 
 3 public class Flower {
 4     int petalCount = 0;
 5     String s = "initial value";
 6 
 7     Flower(int petals) {
 8         petalCount = petals;
 9         System.out.println("Constructor w/ int arg only. petalCount = "
10                 + petalCount);
11     }
12 
13     Flower(String ss) {
14         System.out.println("Constructor w/ String arg only, s = " + ss);
15         s = ss;
16     }
17 
18     Flower(String s, int petals) {
19         this(petals);
20         // this(s); //Can't call two!
21         this.s = s; // Another use of "this"
22         System.out.println("petalCount = " + petalCount + " s = " + s);
23     }
24 
25     Flower() {
26         this("hi", 47);
27         System.out.println("Default constructor(no args)");
28     }
29 
30     void printPetalCount() {
31         // this(11); //Not inside non-Constructor
32         System.out.println("petalCount = " + petalCount + " s = " + s);
33     }
34 
35     public static void main(String[] args) {
36         Flower x = new Flower();
37         x.printPetalCount();
38     }
39 }
View Code

 

猜猜输出是什么?

Constructor w/ int arg only. petalCount = 47
petalCount = 47 s = hi
Default constructor(no args)
petalCount = 47 s = hi

 

变量的初始化顺序

 1 package javaTest;
 2 
 3 class Windows {
 4     Windows(int marker) {
 5         System.out.println("Windows(" + marker + ")");
 6     }
 7 }
 8 
 9 class House {
10     Windows w1 = new Windows(1);
11 
12     House() {
13         System.out.println("House()");
14         w3 = new Windows(33);
15     }
16 
17     Windows w2 = new Windows(2);
18 
19     void f() {
20         System.out.println("f()");
21     }
22 
23     Windows w3 = new Windows(3);
24 }
25 
26 public class OrderOfInitialzation {
27     public static void main(String[] args) {
28         House h = new House();
29         h.f();
30     }
31 }
初始化顺序

 

输出的结果是:

Windows(1)
Windows(2)
Windows(3)
House()
Windows(33)
f()

添加静态变量后的初始化情况

 1 package thinkJava;
 2 
 3 class Bowl {
 4     Bowl(int maker) {
 5         System.out.println("Bowl(" + maker + ")");
 6     }
 7 
 8     void f1(int maker) {
 9         System.out.println("f1(" + maker + ")");
10     }
11 }
12 
13 class Table {
14     static Bowl bowl1 = new Bowl(1);
15 
16     Table() {
17         System.out.println("Table()");
18         bowl2.f1(1);
19     }
20 
21     void f2(int marker) {
22         System.out.println("f2(" + marker + ")");
23     }
24 
25     static Bowl bowl2 = new Bowl(2);
26 }
27 
28 class Cupboard {
29     Bowl bowl3 = new Bowl(3);
30     static Bowl bowl4 = new Bowl(4);
31 
32     Cupboard() {
33         System.out.println("Cupboard()");
34         bowl4.f1(2);
35     }
36 
37     void f3(int maker) {
38         System.out.println("f3(" + maker + ")");
39     }
40 
41     static Bowl bowl5 = new Bowl(5);
42 }
43 
44 public class StaticInitialzation {
45     public static void main(String[] args) {
46         System.out.println("Creating new Cupboard() in main");
47         new Cupboard();
48         System.out.println("Creating new Cupboard() in main");
49         new Cupboard();
50         table.f2(1);
51         cupboard.f3(1);
52     }
53 
54     static Table table = new Table();
55     static Cupboard cupboard = new Cupboard();
56 }
静态成员的初始化顺序

猜测结果是什么?

 1 Bowl(1)
 2 Bowl(2)
 3 Table()
 4 f1(1)
 5 Bowl(4)
 6 Bowl(5)
 7 Bowl(3)
 8 Cupboard()
 9 f1(2)
10 Creating new Cupboard() in main
11 Bowl(3)
12 Cupboard()
13 f1(2)
14 Creating new Cupboard() in main
15 Bowl(3)
16 Cupboard()
17 f1(2)
18 f2(1)
19 f3(1)
初始化结果

 

 4.1 static方法的特性

有些人认为static方法不是"面向对象"的,因为它们的确具有全局函数的语义;使用static方法时,

由于不存在this,所以不是通过"向对象发送消息"的方式完成的。的确,要是在代码中出现了大量的static方法,就该重新考虑自己的设计了。

static是可以修饰属性 方法 内部类 自由块,不能修改方法的局部变量

5 异常抛出

 异常可以直接抛出,也可以循环自恢复。

 1 package exceptions;
 2 
 3 public class Ex5 {
 4     private static int[] ia = new int[2];
 5     private static int x = 5;
 6 
 7     public static void main(String[] args) {
 8         while (true) {
 9             try {
10                 ia[x] = 1;
11                 System.out.println("ia[" + x + "]= " + ia[x]);
12                 break;
13             } catch (Exception e) {
14                 x--;
15                 System.err.println("Caught ArrayIndexOutOfBoundsExceptions");
16                 e.printStackTrace();
17             } finally {
18                 System.out.println("Are we done yet?");
19             }
20         }
21         System.out.println("Now, we are done.");
22 
23     }
24 }
异常恢复模型

结果是:

 

 

 自定义异常

 1 package exceptions;
 2 
 3 class MyExceptions extends Exception {
 4 
 5     private static final long serialVersionUID = 1L;
 6     private int x;
 7 
 8     public MyExceptions() {
 9     }
10 
11     public MyExceptions(String msg) {
12         super(msg);
13     }
14 
15     public MyExceptions(String msg, int x) {
16         super(msg);
17         this.x = x;
18     }
19 
20     public int val() {
21         return x;
22     }
23 
24     public String getMessage() {
25         return "Detial Message: " + x + " " + super.getMessage();
26     }
27 }
28 
29 public class ExtraFeatures {
30     public static void f() throws MyExceptions {
31         System.out.println("Throwing MyException from f()");
32         throw new MyExceptions();
33     }
34 
35     public static void g() throws MyExceptions {
36         System.out.println("Throwing MyException from g()");
37         throw new MyExceptions("Originated in g()");
38     }
39 
40     public static void h() throws MyExceptions {
41         System.out.println("Throwing MyException from h()");
42         throw new MyExceptions("Originated in g()", 47);
43     }
44 
45     public static void main(String[] args) {
46         try {
47             f();
48         } catch (MyExceptions e) {
49             e.printStackTrace(System.out);
50         }
51         try {
52             g();
53         } catch (MyExceptions e) {
54             e.printStackTrace(System.out);
55         }
56         try {
57             h();
58         } catch (MyExceptions e) {
59             e.printStackTrace(System.out);
60             System.out.println("e.val() = " + e.val());
61         }
62     }
63 }
我的异常

 

运行的结果:

 

 

5.1 异常列表/异常说明

 1 package exceptions;
 2 
 3 class ExceptionA extends Exception {
 4 
 5     private static final long serialVersionUID = 1L;
 6 
 7     public ExceptionA(String msg) {
 8         super(msg);
 9     }
10 }
11 
12 class ExceptionB extends Exception {
13 
14     private static final long serialVersionUID = 1L;
15 
16     public ExceptionB(String msg) {
17         super(msg);
18     }
19 }
20 
21 class ExceptionC extends Exception {
22 
23     private static final long serialVersionUID = 1L;
24 
25     public ExceptionC(String msg) {
26         super(msg);
27     }
28 }
29 
30 public class Ex9 {
31     /*
32      * 异常说明使用了附加关键字throws,后面紧接着一个所有潜在异常类型的列表
33      */
34     public static void f(int x) throws ExceptionA, ExceptionB, ExceptionC {
35         if (x > 0)
36             throw new ExceptionA("Exception A");
37         if (x == 0)
38             throw new ExceptionB("Exception B");
39         if (x < 0)
40             throw new ExceptionC("Exception C");
41     }
42 
43     public static void main(String[] args) {
44         try {
45             f(-1);
46             f(0);
47             f(1);
48         } catch (Exception e) {
49             System.out.println("Caught Exception");
50             e.printStackTrace(System.out);
51         }
52     }
53 }
异常说明/throws

输出的结果是

 

 6 继承

构造器的初始化

 1 package reusing;
 2 /*
 3  * 对于基类的正确初始化是至关重要的。
 4  * 在构造器中调用基类构造器来执行初始化。
 5  * 基类构造器具有执行基类初始化方法所需要的知识和能力。
 6  * 导出类构造器会自动调用基类的默认构造器,但是如果基类明确定义了带参数的构造器,
 7  * 就必须在导出类构造器中明确的调用。
 8  */
 9 
10 class Game{
11     Game(int i){
12         System.out.println("Game Constructor");
13     }
14 }
15 class BoardGame extends Game{
16     BoardGame(int i) {
17         super(i);
18         System.out.println("BoardGame Constructor");
19     }
20 }
21 public class Chess extends BoardGame{
22     Chess(int i){
23            super(i);
24            System.out.println("Chess Constructor");
25        }
26     public static void main(String[] args){
27         new Chess(1);
28     }
29 }
构造器初始化

运行结果

1 Game Constructor
2 BoardGame Constructor
3 Chess Constructor
result

 手动清理以及清理顺序例子

  1 package reusing;
  2 class Shape{
  3     Shape(int i){
  4         System.out.println("Shape Constructor.");
  5     }
  6     void dispose(){
  7         System.out.println("Shape dispose.");
  8     }
  9 }
 10 
 11 class Circle extends Shape{
 12     Circle(int i) {
 13         super(i);
 14         System.out.println("Drawing Circle");
 15     }
 16     void dispose(){
 17         System.out.println("Erasing Circle");
 18         super.dispose();
 19     }
 20 }
 21 
 22 class Triangle extends Shape{
 23     Triangle(int i) {
 24         super(i);
 25         System.out.println("Drawing Triangle");
 26     }
 27     void dispose(){
 28         System.out.println("Erasing Triangle");
 29         super.dispose();
 30     }
 31 }
 32 class Line extends Shape{
 33     private int start, end;
 34     Line(int start, int end){
 35         super(start);
 36         this.start = start;
 37         this.end = end;
 38         System.out.println("Drawing Line");
 39     }
 40     void dispose(){
 41         System.out.println("Erasing Line" + start + ", " + end);
 42         super.dispose();
 43     }
 44 }
 45 public class CADSystem extends Shape{
 46     private Circle c;
 47     private Triangle t;
 48     private Line[] lines = new Line[3];
 49     public CADSystem(int i){
 50         super(i + 1);
 51         for(int j = 0; j < lines.length; j++){
 52             lines[j] = new Line(j, j*j);
 53         }
 54         c = new Circle(1);
 55         t = new Triangle(1);
 56         System.out.println("Combined constructor");    
 57     }
 58     public void dispose(){
 59         System.out.println("CADSystem.dispose()");
 60         //The order of cleanup is the reverse
 61         //of the order of initialization;
 62         t.dispose();
 63         c.dispose();
 64         for(int i = lines.length - 1; i >= 0; i--){
 65             lines[i].dispose();
 66         }
 67     }
 68     
 69     public static void main(String[] args){
 70         CADSystem x = new CADSystem(47);
 71         try{
 72             
 73         }finally{
 74             x.dispose();
 75         }
 76     }
 77     
 78     /*
 79      * Shape Constructor.
 80      * Shape Constructor.
 81      * Drawing Line
 82      * Shape Constructor.
 83      * Drawing Line
 84      * Shape Constructor.
 85      * Drawing Line
 86      * Shape Constructor.
 87      * Drawing Circle
 88      * Shape Constructor.
 89      * Drawing Triangle
 90      * Combined constructor
 91      * CADSystem.dispose()
 92      * Erasing Triangle
 93      * Shape dispose.
 94      * Erasing Circle
 95      * Shape dispose.
 96      * Erasing Line2,4
 97      * Shape dispose.
 98      * Erasing Line1,1
 99      * Shape dispose.
100      * Erasing Line0,0
101      * Shape dispose.
102      * 
103      */
104 
105 }
清理代码

 7 多态

私有方法有多态吗?

 1 package ploymorphism;
 2 
 3 class Derived extends PrivateOverride{
 4     public void f(){
 5         System.out.println("public f()");
 6     }
 7 }
 8 
 9 /*
10  * 多态不能覆盖父类的私有方法,尽量避免子类和父类的私有方法名字一致,从而避免引起混淆。
11  * 下面的代码输出是什么?把f()的权限公开,结果又怎样?
12  */
13 public class PrivateOverride {
14    private void f(){
15        System.out.println("private f()");
16    }
17    public static void main(String[] args){
18        PrivateOverride po = new Derived();
19        po.f();
20    }
21 }
22 
23 /*
24  * private f()
25  */
PrivateOverride

 公开域有多态吗?

 1 package ploymorphism;
 2 
 3 class Super {
 4     public int field = 0;
 5 
 6     public int getField() {
 7         return field;
 8     }
 9 }
10 
11 class Sub extends Super {
12     public int field = 1;
13 
14     public int getField() {
15         return field;
16     }
17 
18     public int getSuperField() {
19         return super.field;
20     }
21 }
22 
23 public class FieldAccess {
24     public static void main(String[] args) {
25         Super sup = new Sub(); // Up casting
26         System.out.println("sup.field = " + sup.field + ", sup.getField() = "
27                 + sup.getField());
28         Sub sub = new Sub();
29         System.out.println("sub.field = " + sub.field + ", sub.getField() = "
30                 + sub.getField() + ", sub.getSuperField = "
31                 + sub.getSuperField());
32     }
33 
34 }
35 
36 /*
37  * 任何域的访问操作都将有编译器解析,因此不是多态的。
38  * Sub实际上有两个field的域。它自己的和从Super处得到的。
39  * 引用Sub中的域field时所产生的默认域并非Super版本的域。 
40  *
41  */
42 
43 /*
44  * Output:
45  * sup.field = 0, sup.getField() = 1
46  * sub.field = 1, sub.getField() = 1, sub.getSuperField = 0
47  * 
48  */
FieldAccess

 静态方法有多态吗?

 1 package ploymorphism;
 2 class StaticSuper{
 3     public static String staticGet(){
 4         return "Base staticGet";
 5     }
 6     public String dynamicGet(){
 7         return "Base dynamicGet()";
 8     }
 9 }
10 class StaitcSub extends StaticSuper{
11     public static String staticGet(){
12         return "Derived staticGet()";
13     }
14     public String dynamicGet(){
15         return "Derived dynamicGet()";
16     }
17 }
18 public class StaticPolymorphism {
19      public static void main(String[] args){
20          StaticSuper sup = new StaitcSub();
21          System.out.println(sup.staticGet());
22          System.out.println(sup.dynamicGet());
23      }
24 }
25 
26 /*
27  * 如果某个方法是静态的,它的行为就不具有多态性。
28  * 静态方法是与类,而非单个对象相关联的。
29  * 
30  * Outputs:
31  * 
32  * Base staticGet
33  * Derived dynamicGet()
34  */
StaticPolymorphism

只有普通的公开方法有多态的特性。

含有构造器,继承,静态域的初始化顺序

 1 package ploymorphism;
 2 
 3 class Meal {
 4     Meal() {
 5         System.out.println("Meal()");
 6     }
 7 }
 8 
 9 class Bread {
10     Bread() {
11         System.out.println("Bread()");
12     }
13 }
14 
15 class Chess {
16     Chess() {
17         System.out.println("Chess()");
18     }
19 }
20 
21 class Lettuce {
22     Lettuce() {
23         System.out.println("Lettuce()");
24     }
25 }
26 
27 class Lunch extends Meal {
28     Lunch() {
29         System.out.println("Lunch()");
30     }
31 }
32 
33 class ProtableLunch extends Lunch {
34     ProtableLunch() {
35         System.out.println("ProtableLunch()");
36     }
37 }
38 
39 public class SandWitch extends ProtableLunch{
40     
41     private Bread b = new Bread();
42     private Chess c = new Chess();
43     private Lettuce l = new Lettuce();
44     
45     private static ProtableLunch pp = new ProtableLunch();//1
46     private static Lunch ll = new Lunch();//2
47     
48     public SandWitch() {
49         System.out.println("SandWitch()");
50     }
51 
52     public static void main(String[] args) {
53         new SandWitch();//3
54     }
55 }
56 
57 /*
58  * 初始化顺序,调用基类构造器
59  * 按声明顺序调用成员初始化的方法
60  * 调用导出类构造器的主体
61  * 先静态域,静态方法,数据域,构造器,普通方法
62  * 
63  */
64 
65 /*
66  * Outputs:
67  * 
68  * Meal() 
69  * Lunch() 
70  * ProtableLunch() 
71  * Meal()
72  * Lunch()
73  * Meal() 
74  * Lunch() 
75  * ProtableLunch() 
76  * Bread() 
77  * Chess() 
78  * Lettuce() 
79  * SandWitch()
80  * 
81  * 
82  */
初始化顺序

8  数组

类似于C系列的函数求解

 1 package arrays;
 2 
 3 import java.util.Arrays;
 4 import java.util.Random;
 5 
 6 public class IceCream {
 7     private static Random rand = new Random(47);
 8     static final String[] FLAVORS = { "Chocolate", "Strawberry",
 9             "Vanilla Fudge Swirl", "Mint Chip", "Mocha Almond Fudge",
10             "Rum Raisin", "Praline Cream", "Mud Pie", };
11 
12     public static String[] flavorSet(int n) {
13         if (n > FLAVORS.length) {
14             throw new IllegalArgumentException("Set to big");
15         }
16         String[] results = new String[n];
17         boolean[] picked = new boolean[FLAVORS.length];
18         for (int i = 0; i < n; i++) {
19             int t;
20             do {
21                 t = rand.nextInt(FLAVORS.length);
22             } while (picked[t]);
23             results[i] = FLAVORS[t];
24             picked[t] = true;
25         }
26         return results;
27     }
28 
29     public static void main(String[] args) {
30         for (int i = 0; i < 7; i++) {
31             System.out.println(Arrays.toString(flavorSet(4)));
32         }
33     }
34 }
35 
36 /*
37  * OutPuts:
38  * 
39  * [Rum Raisin, Mint Chip, Mocha Almond Fudge, Chocolate] 
40  * [Strawberry, MochaAlmond Fudge, Mint Chip, Rum Raisin] 
41  * [Vanilla Fudge Swirl, Mud Pie,Chocolate, Mocha Almond Fudge] 
42  * [Praline Cream, Strawberry, Mocha AlmondFudge, Mint Chip] 
43  * [Mint Chip, Strawberry, Praline Cream, Chocolate]
44  * [Chocolate, Praline Cream, Mocha Almond Fudge, Mint Chip] 
45  * [Mud Pie,Strawberry, Mint Chip, Rum Raisin]
46  * 
47  */
数组随机组

9 泛型

 Java中的泛型需要与C++进行一番比较,理由有二:首先,了解C++模板的默写方面,有助于理解泛型的基础。

同时,也可以了解Java的局限,以及为什么有这些限制。最终帮你理解,Java泛型的边界在哪里。理解了边界所在,

才能成为程序高手(不必浪费时间在死胡同里乱转)。第二个原因是,在Java社区中,人们普遍对C++模板有一种误解,

而这种误解可能误导你,令你在理解泛型的意图时产生偏差。

10 内部类

package innerclasses;
/*
 * 接口就相当于声明语句
 */
interface Selector {
    public int dex = 0;
    boolean end();

    Object current();

    void next();
}

public class Sequence {
    private static Object[] item;
    private int next;

    public Sequence(int size) {
        item = new Object[size];
    }

    public void add(Object x) {
        if (next < item.length) {
            item[next++] = x;
        }
    }

    /*
     * 内部类可以访问外围类的字段和方法, 加static关键字表示嵌套类(静态内部类)
     */
    public static class SequenceSelector implements Selector {
        private int i = 0;
        

        public boolean end() {
            return i == item.length;
        }

        public Object current() {
            return item[i];
        }

        public void next() {
            if (i < item.length) {
                i++;
            }
        }
    }

    public Selector selector() {
        return new SequenceSelector();
    }

    public static void main(String[] args) {
        Sequence sequence = new Sequence(10);
        for (int i = 0; i < 10; i++) {
            sequence.add(Integer.toString(i));
        }
        Selector selector = sequence.selector();
        while (!selector.end()) {
            System.out.print(selector.current() + " ");
            selector.next();
        }
    }

}

class ABC {
    /*
     * 先实例化外围类
     */
    Sequence aSequence = new Sequence(5);
    /*
     * 实例化的外围类生成构造器
     */
    Sequence.SequenceSelector aSelector = new Sequence.SequenceSelector();
    int x = Selector.dex;
}
内部类接口实现

 11 容器、迭代器

迭代器能够将遍历的操作与序列底层的结构分离。正由于此,我们有时会说;迭代器统一了对容器的访问方式。

 

posted @ 2014-11-10 15:28  kongmeng  阅读(304)  评论(0编辑  收藏  举报