Chinaunix首页 | 论坛 | 博客
  • 博客访问: 294809
  • 博文数量: 179
  • 博客积分: 2995
  • 博客等级: 少校
  • 技术积分: 2100
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-13 10:21
文章分类

全部博文(179)

文章存档

2011年(1)

2010年(28)

2009年(150)

我的朋友

分类: Java

2009-11-13 15:25:58

深刻理解Java编程的7个例子
深刻理解Java编程的7个例子   佟强 2009年11月7日 http://blog.csdn.net/microtong

 1. 阅读下列代码回答问题(第一个Java程序,理解PATH和CLASSPATH,学会使用javac和java命令)

view plaincopy to clipboardprint?

   1. package cn.edu.uibe;  
   2. public class HelloWorld {  
   3.     public static void main(String[] args) {  
   4.         System.out.println("Hello World!");  
   5.     }  
   6. }  

package cn.edu.uibe; public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } }

问:

(1)上面代码所在的源文件的文件名是_______________?
(2)在DOS提示符下,当前目录为该源文件所在的目录,PATH环境变量已包含编译程序所在的路径,编译目标路径为“D:\classes”,编译命令行是_____________?
(3)为了让Java解释器能够找到编译后的类文件,需要如何设置环境变量___________?
(4)在正确设置了相关的环境变量之后,运行HelloWorld类的命令行是____________?


答案:

(1)HelloWorld.java,公共类必须定义在和类名同名的文件中,文件名区分大小写。

(2)javac -d D:\classes HelloWorld.java ,-d给出输出目录,javac会在D:\classes创建包的目录层次结构cn\edu\uibe\HelloWorld.class

(3)set CLASSPATH=.;D:\classses,CLASSSPATH给出Java寻找.class文件的多个路径,路径之间用分号分隔,“.”表示当前路径。

(4)java cn.edu.uibe.HelloWorld,注意需要给出包名,类名后面不要加“.class”。

2. 阅读下列代码回答问题(关于private的理解)

view plaincopy to clipboardprint?

   1. public class Light {  
   2.     private int brightness = 5;  
   3.     public void brighten(Light another){  
   4.         another.brightness++;  
   5.     }  
   6.     public static void main(String[] args) {  
   7.         Light light1 = new Light();  
   8.         Light light2 = new Light();  
   9.         light1.brighten(light2);  
  10.     }  
  11. }  

public class Light { private int brightness = 5; public void brighten(Light another){ another.brightness++; } public static void main(String[] args) { Light light1 = new Light(); Light light2 = new Light(); light1.brighten(light2); } }

问:上面代码Java编译器是否会给出错误提示?为什么?

答案:不会出现错误提示,private限制了私有变量只能被同一个类访问,但是没有限制同一个类的不同对象之间互相访问私有变量。实际上,private是在编译时进行检查,如果想限制同类对象之间互相访问,需要在动态运行时实现,开销较大,而且没有必要。

3. 阅读下列代码回答问题(关于多态性的理解)

view plaincopy to clipboardprint?

   1. class Base {  
   2.     int i=1;  
   3.     void f(){  
   4.         System.out.println("Base.f()");  
   5.     }  
   6.     void g(){  
   7.     f(); //会调用上面的f()方法吗?  
   8.     }  
   9. }  
  10. public class Derived extends Base { //继承了Base类  
  11.     int i=2; //Derived类的对象有1个i还是2个i呢? 答:2个  
  12.     void f(){ //覆盖override了f()方法  
  13.         System.out.println("Derived.f()");  
  14.     }  
  15.     public static void main(String[] args) {  
  16.         Derived d = new Derived(); //创建子类对象  
  17.         Base b = d; //没有创建对象,仅仅是父类引用指向了子类对象  
  18.         d.f(); //将会输出Derived.f()  
  19.         b.f(); //也会输出Derived.f(),方法具有多态性  
  20.         System.out.println(d.i); //输出的是2,d.i访问子类中定义的变量i  
  21.         System.out.println(b.i); //输出的是1,b.i访问的是父类中定义的变量i,成员变量是不会动态绑定而表现出多态性的。        
  22.         d.g(); //输出Derived.f()  
  23.         b.g(); //也输出Derived.f(),从父类中调用被覆盖的方法f(),也将调用到子类中更具体的方法。  
  24.     }  
  25. }  

class Base { int i=1; void f(){ System.out.println("Base.f()"); } void g(){ f(); //会调用上面的f()方法吗? } } public class Derived extends Base { //继承了Base类 int i=2; //Derived类的对象有1个i还是2个i呢? 答:2个 void f(){ //覆盖override了f()方法 System.out.println("Derived.f()"); } public static void main(String[] args) { Derived d = new Derived(); //创建子类对象 Base b = d; //没有创建对象,仅仅是父类引用指向了子类对象 d.f(); //将会输出Derived.f() b.f(); //也会输出Derived.f(),方法具有多态性 System.out.println(d.i); //输出的是2,d.i访问子类中定义的变量i System.out.println(b.i); //输出的是1,b.i访问的是父类中定义的变量i,成员变量是不会动态绑定而表现出多态性的。 d.g(); //输出Derived.f() b.g(); //也输出Derived.f(),从父类中调用被覆盖的方法f(),也将调用到子类中更具体的方法。 } }

问: 写出上面代码的输出?

答案:参见代码注释,子类和父类中定义同名的变量时,仅仅是隐藏了,变量没有多态性;而对于覆盖的方法,Java表现出多态性,

会调用更具体的子类里面的方法,无论从哪里调用,无论使用什么引用类型调用。

4.阅读下列代码回答问题(关于匿名内部类的理解)

view plaincopy to clipboardprint?

   1. interface A {  
   2.     void f();  
   3. }  
   4. public class B {  
   5.     public void f(A a) {  
   6.     }  
   7.     public static void main(String[] args) {  
   8.         B b= new B();  
   9.         b.f(new A() {  
  10.             public void f() {  
  11.             }  
  12.         });  
  13.     }  
  14. }  

interface A { void f(); } public class B { public void f(A a) { } public static void main(String[] args) { B b= new B(); b.f(new A() { public void f() { } }); } }

问:请解释语句
b.f(new A() {
    public void f() {
    }
});
的含义与作用。

答案:

   这个语句在参数表中定义了一个匿名内部类,这个匿名内部类实现了接口A,实例化了一个匿名内部类的对象,并将这个对象传递给了接收接口A作为参数的方法f(A a)。需要注意的是接口A中的方法f()和类B中的方法f(A a)没有任何关系,是不同的方法。


5. 阅读下列代码回答问题(关于static的理解)

view plaincopy to clipboardprint?

   1. public class Static {  
   2.     static int i = 0;  
   3.     int j=0;  
   4.     public static void main(String[] args) {  
   5.         Static s1 = new Static();  
   6.         Static s2 = new Static();  
   7.         s1.i++;  
   8.         s2.i++;  
   9.         s1.j++;  
  10.         s2.j++;  
  11.         System.out.println(s1.i);  
  12.         System.out.println(s1.j);  
  13.         System.out.println(s2.i);  
  14.         System.out.println(s2.j);  
  15. }  
  16. }  

public class Static { static int i = 0; int j=0; public static void main(String[] args) { Static s1 = new Static(); Static s2 = new Static(); s1.i++; s2.i++; s1.j++; s2.j++; System.out.println(s1.i); System.out.println(s1.j); System.out.println(s2.i); System.out.println(s2.j); } }

问:写出上面代码的输出。

答案: 2 1 2 1,i是静态变量,类的所有实例共享同一个i,通常我们不通过引用变量访问静态变量,而是通过类名访问Static.i,注意Static是我们自己定义的类名,而小写的static是关键字,表示静态的,为类的所有实例共享的变量或方法。j是实例变量,每个对象具有不同的,属于其自身的一个变量j。

6. 阅读下列代码回答问题(关于引用变量的理解)

view plaincopy to clipboardprint?

   1. class Counter{  
   2.     int i=0;  
   3. }  
   4. public class Reference {  
   5.     public void plus(int i){  
   6.         i++; //不会改变传递进来的参数的值,Java传递基本类型时进行了值的拷贝  
   7.     }  
   8.     public void plus(Counter c){  
   9.         c.i++; //会改变,因为c是一个引用变量,相当于指针  
  10.     }  
  11.     public void create(Counter c){  
  12.         c = new Counter();   
  13.                   c.i++; //不会改变,因为c执行了另外一个新建的对象  
  14.     }     
  15.     public static void main(String[] args) {  
  16.         int i = 0;  
  17.         Reference r = new Reference();  
  18.         Counter c1 = new Counter();  
  19.         Counter c2 = new Counter();       
  20.         r.plus(i);  
  21.         r.plus(c1);  
  22.         r.create(c2);         
  23.         System.out.println(i);  
  24.         System.out.println(c1.i);  
  25.         System.out.println(c2.i);  
  26.     }  
  27. }  

class Counter{ int i=0; } public class Reference { public void plus(int i){ i++; //不会改变传递进来的参数的值,Java传递基本类型时进行了值的拷贝 } public void plus(Counter c){ c.i++; //会改变,因为c是一个引用变量,相当于指针 } public void create(Counter c){ c = new Counter(); c.i++; //不会改变,因为c执行了另外一个新建的对象 } public static void main(String[] args) { int i = 0; Reference r = new Reference(); Counter c1 = new Counter(); Counter c2 = new Counter(); r.plus(i); r.plus(c1); r.create(c2); System.out.println(i); System.out.println(c1.i); System.out.println(c2.i); } }

问:上面代码输出是?

答案:参考代码注释,输出应该是:0 1 0

7. 阅读下列代码回答问题(关于异常的理解)

view plaincopy to clipboardprint?

   1. class MyException extends Exception{  
   2.     public MyException(String message){  
   3.         super(message);  
   4.     }  
   5. }  
   6. public class ExceptionDemo{  
   7.     public void f(int num) throws MyException {  
   8.         if(num<0){  
   9.             throw new MyException("参数不能为负数!");  
  10.         }  
  11.         System.out.println(num);  
  12.         }  
  13.     public void g(){  
  14.         try{  
  15.             f(1);  
  16.             f(3);  
  17.             f(0);  
  18.             f(-1);  
  19.             f(2);  
  20.             f(-5);  
  21.         }catch(MyException e){  
  22.             System.err.println(e.getMessage());  
  23.             return;//会立即返回吗?答:不会!  
  24.         }finally{  
  25.            System.out.println("无论什么时候!");     
  26.         }  
  27.     }  
  28.     public static void main(String[] args) {  
  29.         ExceptionDemo demo = new ExceptionDemo();  
  30.         demo.g();  
  31.     }  
  32. }  

class MyException extends Exception{ public MyException(String message){ super(message); } } public class ExceptionDemo{ public void f(int num) throws MyException { if(num<0){ throw new MyException("参数不能为负数!"); } System.out.println(num); } public void g(){ try{ f(1); f(3); f(0); f(-1); f(2); f(-5); }catch(MyException e){ System.err.println(e.getMessage()); return;//会立即返回吗?答:不会! }finally{ System.out.println("无论什么时候!"); } } public static void main(String[] args) { ExceptionDemo demo = new ExceptionDemo(); demo.g(); } }

问:上面代码输出是?

答案:输出是:1 3 0 参数不能为负数! 无论什么时候!

try语句块里面的一行代码抛出了异常,后续代码就不再执行了,而是转到catch开始匹配异常类型。finally语句块里面的代码始终会被执行,即使在catch语句块里面有行return语句也不会立即返回,Java确保finally语句块执行完函数才会返回。
================================================================================

阅读(478) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~