找回密码
 FreeOZ用户注册
查看: 2055|回复: 24
打印 上一主题 下一主题

[论坛技术] 茴字的四种写法之Java的小秘密

[复制链接]
跳转到指定楼层
1#
发表于 23-6-2009 22:16:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?FreeOZ用户注册

x
下面是一系列Java程序中容易误解或忽略的问题,有些程序是错的,
有些程序则需要你分析结果。试一试你知不知道茴字的各种写法。

写法一之NaN问题
就这样读代码,看能不能猜出结果?
  1. public class DoubleNaNTest
  2. {
  3.     public static void main(String args[]) {
  4.         double myNaN = Math.sqrt(-1);   //create a NaN value
  5.         System.out.println("DEBUG value = " + myNaN);

  6.         doTest(0.0, myNaN);
  7.         doTest(1.0/0.0, myNaN);
  8.         doTest(-1.0/0.0, myNaN);
  9.         doTest(myNaN, myNaN);

  10.     }

  11.     private static void doTest(double x, double y)
  12.     {
  13.         System.out.println("x = " + x + " , y = " + y + ", x < y -> " + (x > y));
  14.         System.out.println("x = " + x + " , y = " + y + ", x <= y -> " + (x <= y));
  15.         System.out.println("x = " + x + " , y = " + y + ", x > y -> " + (x > y));
  16.         System.out.println("x = " + x + " , y = " + y + ", x >= y -> " + (x >= y));
  17.         System.out.println("x = " + x + " , y = " + y + ", x == y -> " + (x == y));
  18.         System.out.println("x = " + x + " , y = " + y + ", x != y -> " + (x != y));
  19.     }
  20. }
复制代码

[ 本帖最后由 key 于 25-6-2009 10:15 编辑 ]
回复  

使用道具 举报

2#
发表于 23-6-2009 22:31:24 | 只看该作者
回复  

使用道具 举报

3#
 楼主| 发表于 23-6-2009 23:15:26 | 只看该作者

继续茴字的四种写法:Arithmetic Promotion

试分析下面的程序结果:
  1.   1 public class ArithmeticPromotionTest {
  2.   2     public static void main(String [] args) {
  3.   3         byte x = 1;
  4.   4         byte y = 2;
  5.   5
  6.   6         byte z = x + y;
  7.   7
  8.   8         System.out.println(z);
  9.   9     }
  10. 10 }
  11. 11
复制代码

[ 本帖最后由 key 于 23-6-2009 22:16 编辑 ]
回复  

使用道具 举报

4#
 楼主| 发表于 23-6-2009 23:30:55 | 只看该作者

茴字四种写法三:Autoboxing

  1. public class AutoBoxingTest {
  2.     public void test(Integer v)
  3.     {
  4.         System.out.println("value - " + v);
  5.     }

  6.     public void test2(int v)
  7.     {
  8.         System.out.println("value - " + v);
  9.     }

  10.     public static void main(String args[])
  11.     {
  12.         AutoBoxingTest abt = new AutoBoxingTest();

  13.         abt.test(10);
  14.         abt.test2(new Integer(100));

  15.         System.out.println(123 instanceof Integer);
  16.         System.out.println(123.equals(123));
  17.     }

  18. }
复制代码

[ 本帖最后由 key 于 24-6-2009 14:52 编辑 ]
回复  

使用道具 举报

5#
 楼主| 发表于 24-6-2009 00:43:31 | 只看该作者

茴字四种写法四:static block

  1. public class StaticBlockTest2 {
  2.         static{
  3.                 System.out.println("Now executing static block in class 2");
  4.                 System.out.flush();
  5.         }

  6.         public StaticBlockTest2() {
  7.                 System.out.println("Now executing constructor of class 2");
  8.         }
  9. }
复制代码
  1. public class StaticBlockTest {
  2.     public static void main(String [] args) {
  3.         System.out.println("Now executing main() method");
  4.         System.out.flush();
  5.         StaticBlockTest2 sbt2 = new StaticBlockTest2();
  6.     }

  7.     static {
  8.         System.out.println("Now executing static block");
  9.         System.out.flush();
  10.     }
  11. }
复制代码
回复  

使用道具 举报

6#
 楼主| 发表于 24-6-2009 01:23:27 | 只看该作者

茴字的四种写法五:inner class

  1. public class InnerClassTest {
  2.         public class InnerTest {
  3.                 public void test(){
  4.                         System.out.println("hello world");
  5.                 }
  6.         }
  7. }
复制代码
  1. public class InnerClassTest2 {
  2.     public static void main(String args[]){
  3.         InnerClassTest ict = new InnerClassTest();
  4.         ict.InnerTest x = new ict.InnerTest();
  5.         x.test();
  6.     }
  7. }
复制代码
补充

上面的Test2是错的,正确的写法是:
  1. public class InnerClassTest2 {
  2.     public static void main(String args[]){
  3.         InnerClassTest ict = new InnerClassTest();
  4.         InnerClassTest.InnerTest x = ict.new InnerTest();
  5.         x.test();
  6.     }
  7. }
复制代码

[ 本帖最后由 key 于 24-6-2009 00:36 编辑 ]
回复  

使用道具 举报

7#
 楼主| 发表于 24-6-2009 01:30:07 | 只看该作者

茴字四种写法五:Inner Class 2

  1. public class InnerClassTest3 {
  2.     public class InnerTest {
  3.         static int x = 100;
  4.     }

  5.     public void test(){
  6.         System.out.println(InnerTest.x);
  7.     }
  8. }
复制代码
回复  

使用道具 举报

8#
 楼主| 发表于 24-6-2009 09:56:08 | 只看该作者

茴字四种写法六:Enum相加问题

  1. public class EnumAdditionTest {
  2.   enum TestEnum { HELLO, WORLD };
  3.   public void doTest() {
  4.       TestEnum a = TestEnum.HELLO, b = TestEnum.WORLD;
  5.       System.out.println(a + b);
  6.   }
  7. }
复制代码
回复  

使用道具 举报

9#
发表于 24-6-2009 11:33:41 | 只看该作者
what's the difference between floor 3 and 4?
回复  

使用道具 举报

10#
 楼主| 发表于 24-6-2009 15:53:30 | 只看该作者
回复  

使用道具 举报

11#
 楼主| 发表于 24-6-2009 16:34:42 | 只看该作者

茴字四种写法之七:Array Implicit Conversion

  1. 1. int [] ix = int [] { 1, 2, 3 };
  2. 2. long [] lx = ix;
  3. 3. Integer [] oix = ix;
  4. 4. Object [] ox = oix;
  5. 5. Serializable sx = oix;
  6. 6. Cloneable cx = oix;
复制代码
上面哪些语句不合法?
回复  

使用道具 举报

12#
发表于 24-6-2009 23:51:43 | 只看该作者
真高深的~~~~~~~~~~~~~`
回复  

使用道具 举报

13#
 楼主| 发表于 25-6-2009 11:06:30 | 只看该作者

茴字四种写法之八:String +

分析下面的程序,回答两个问题:
1. 程序的输出结果是什么?
2. 运行过程中,一共产生了多少个对象?
  1. public class StringLiteralAddTest {
  2.     public static void main(String [] args){
  3.         String hello = "hello";
  4.         String newHello = "he" + "llo";

  5.         System.out.println(hello == newHello);
  6.     }
  7. }
复制代码
回复  

使用道具 举报

14#
 楼主| 发表于 25-6-2009 11:08:56 | 只看该作者

茴字四种写法九:String non-literal +

和八同样的问题,看下面程序:
  1.   1 public class StringLiteralAddTest {
  2.   2     public static void main(String [] args){
  3.   3         String hello = "hello";
  4.   4         String he    = "he";
  5.   5         String newHello = he + "llo";
  6.   6
  7.   7         System.out.println(hello == newHello);
  8.   8     }
  9.   9 }
复制代码
回复  

使用道具 举报

15#
 楼主| 发表于 25-6-2009 11:21:55 | 只看该作者

茴字四种写法之十:StringBuffer问题

  1.   1 public class StringBufferSetLengthTest{
  2.   2     public static void main(String [] args){
  3.   3         StringBuffer sb = new StringBuffer("hello");
  4.   4         sb.setLength(100);
  5.   5         sb.append("world");
  6.   6
  7.   7         System.out.println(sb.toString());
  8.   8
  9.   9         String x = sb.toString();
  10. 10         int ix = x.charAt(10);
  11. 11         System.out.println(ix);
  12. 12     }
  13. 13 }
复制代码
回复  

使用道具 举报

16#
发表于 26-6-2009 01:11:38 | 只看该作者
牛比,我不想programming...
回复  

使用道具 举报

17#
 楼主| 发表于 26-6-2009 11:40:26 | 只看该作者

茴字的四种写法之十一:to be or not to be -- a constructor

下面的程序会有什么输入?:
1. hello
2. world
3. compiler error
  1. public class NotConstructorTest {
  2.     public NotConstructorTest() {
  3.         System.out.println("world");
  4.     }

  5.     public void NotConstructorTest() {
  6.         System.out.println("hello");
  7.     }

  8.     public static void main(String [] args){
  9.         NotConstructorTest nct = new NotConstructorTest();
  10.     }
  11. }
复制代码
回复  

使用道具 举报

18#
 楼主| 发表于 26-6-2009 11:52:16 | 只看该作者

茴字的四种写法之十二:dynamic binding与static binding

试说出下面的程序的运行结果:
1. 10
2. 100
3. 楼主很变态
  1. public class X { public int x = 10; }
  2. public class Y extends X { public int x = 100; }

  3. public class M {
  4.   public static void main(String [] args){
  5.         X x = new Y();
  6.         System.out.println(x.x);
  7.   }
  8. }
复制代码
回复  

使用道具 举报

19#
 楼主| 发表于 26-6-2009 13:09:22 | 只看该作者

茴字四种写法之十三:Inner Class in Interfaces

下面的程序有错,哪里出错?请说明理由,并说明如何改正:
  1.   1 public interface InnerClassInterfaceTest {
  2.   2     public class InnerClass {
  3.   3         public void test() {
  4.   4             System.out.println("hello from inner");
  5.   5         }
  6.   6     }
  7.   7
  8.   8     public static class StaticNestedClass {
  9.   9         public void test() {
  10. 10             System.out.println("hello from nested class");
  11. 11         }
  12. 12     }
  13. 13 }
复制代码
  1.   1 public class InnerClassInterfaceMainTest {
  2.   2     public static void main(String [] args){
  3.   3         InnerClassInterfaceTest icit = new
  4.   4             InnerClassInterfaceTest() {};
  5.   5
  6.   6         InnerClassInterfaceTest.InnerClass in =
  7.   7             icit.new InnerClass();
  8.   8
  9.   9         InnerClassInterfaceTest.StaticNestedClass snc =
  10. 10             new InnerClassInterfaceTest.StaticNestedClass();
  11. 11
  12. 12         in.test();
  13. 13         snc.test();
  14. 14     }
  15. 15 }
  16. 16
复制代码
回复  

使用道具 举报

20#
 楼主| 发表于 26-6-2009 23:23:41 | 只看该作者

茴字四种写法之十四:神奇的字符

看下面的程序,试讨论它的输出:
  1.   1 public class X extends Y{
  2.   2     private char x = '\u000A';
  3.   3
  4.   4     public static void main(String [] args){
  5.   5         System.out.println(x);
  6.   6     }
  7.   7 }
复制代码
回复  

使用道具 举报

21#
 楼主| 发表于 28-6-2009 20:24:12 | 只看该作者

茴字四种写法之十五:当Var-arg遇上Autoboxing

判断下面两个程序,请选择:
(1) 两个都没有错
(2) 两个都有错
(3) 第二个程序错了

程序一
  1. 1 public class VarArgAutoboxingTest {
  2. 2     public void test(Integer ... ks){
  3. 3     }
  4. 4
  5. 5     public void test(int ... ks){
  6. 6     }
  7. 7 }
复制代码
程序二
  1.   1 public class VarArgAutoboxingTest {
  2.   2     public void test(Integer ... ks){
  3.   3     }
  4.   4
  5.   5     public void test(int ... ks){
  6.   6     }
  7.   7
  8.   8     public void test() {
  9.   9         test(1);
  10. 10     }
  11. 11
  12. 12 }
复制代码
回复  

使用道具 举报

22#
 楼主| 发表于 29-6-2009 00:32:37 | 只看该作者

茴字四种写法之十六:dynamic binding vs. static binding

分析下面的代码,判断:
(1) 编译出错
(2) 500
(3) 1000
(4) 1500
(5) 2000
  1. class Super {
  2.   public int x = 500;
  3.   public int getX() { return x; }
  4. }
  5. class Derived {
  6.   public int x = 1000;
  7.   public int getX() { return x; }
  8. }

  9. public class Main {
  10.   public static void main(String [] args) {
  11.     Super s = new Derived();
  12.     System.out.println(s.getX() + s.x);
  13.   }
  14. }
复制代码
回复  

使用道具 举报

23#
 楼主| 发表于 29-6-2009 10:08:57 | 只看该作者

茴字四种写法之十七:boolean 转换

判断输出
  1.   1 public class CodeMain{
  2.   2     public static void main(String [] args){
  3.   3         TheBooleanGame bg = new TheBooleanGame();
  4.   4         bg.printBoolean();
  5.   5     }
  6.   6 }
  7.   7
  8.   8 class TheBooleanGame {
  9.   9     public void printBoolean() {
  10. 10         String s1 = "1";
  11. 11         String s2 = "0";
  12. 12         String s3 = "null";
  13. 13         String s4 = "True";
  14. 14         String s5 = null;
  15. 15         Boolean b = new Boolean("True");
  16. 16         boolean b2 = false;
  17. 17
  18. 18         System.out.printf("%b %b %b %b %b %b %b",
  19. 19             s1, s2, s3, s4, s5, b, b2);
  20. 20     }
  21. 21 }
复制代码
回复  

使用道具 举报

24#
 楼主| 发表于 29-6-2009 10:11:10 | 只看该作者
原帖由 key 于 29-6-2009 09:08 发表
判断输出  1 public class CodeMain{
  2     public static void main(String [] args){
  3         TheBooleanGame bg = new TheBooleanGame();
  4         bg.printBoolean();
  5     }
  6 }
  7
  8  ...


加多几行:
  1.   1 public class CodeMain{
  2.   2     public static void main(String [] args){
  3.   3         TheBooleanGame bg = new TheBooleanGame();
  4.   4         bg.printBoolean();
  5.   5     }
  6.   6 }
  7.   7
  8.   8 class TheBooleanGame {
  9.   9     public void printBoolean() {
  10. 10         String s1 = "1";
  11. 11         String s2 = "0";
  12. 12         String s3 = "null";
  13. 13         String s4 = "True";
  14. 14         String s5 = null;
  15. 15         Boolean b = new Boolean("True");
  16. 16         boolean b2 = false;
  17. 17         Integer i1 = 1;
  18. 18         Integer i2 = 0;
  19. 19         Integer i3 = null;
  20. 20         int x = 0;
  21. 21         System.out.printf("%b %b %b %b %b %b %b %b %b %b %b",
  22. 22             s1, s2, s3, s4, s5, b, b2, i1, i2, i3, x);
  23. 23     }
  24. 24 }
复制代码

[ 本帖最后由 key 于 29-6-2009 09:15 编辑 ]
回复  

使用道具 举报

25#
 楼主| 发表于 29-6-2009 10:34:51 | 只看该作者

为什么会这样?

int x = 0;
System.out.printf("%b", x);

得到的是true,这会让一个C/C++程序员疯掉。
这是因为Java在处理这个printf的时候,会做下面的工作:
1. 把int x转成Integer ix,即做autoboxing,值不变,还是0
2. 尝试显示,因为Integer ix != null,通过%b显示时,由于对象不是null,所以相当于 b = true
3. 通过String.valueOf(b)显示成"true"

总结起来,在.printf("%b")或.format("%b")的时候,只有两种情况会显示false,其他都是true,
这两种情况是:
1. boolean或Boolean值,false
2. 对象null

另外,对于%b,是不会出现runtime exception的

而%c, %d, %f都有可能出现runtime exception,而这三个标志对于boolean都是不接受,这也是和C程序中
非常不同的地方。更有过份的地方,用%f是不能显示integer值的,如下面的程序会引起RuntimeException
System.out.println("%f", 10);

原因?看看SDK的源代码就知道了:
显示Integer
  1. 2694         private void printInteger(Object arg, Locale l) throws IOException     {
  2. 2695             if (arg == null)
  3. 2696                 print("null");
  4. 2697             else if (arg instanceof Byte)
  5. 2698                 print(((Byte)arg).byteValue(), l);
  6. 2699             else if (arg instanceof Short)
  7. 2700                 print(((Short)arg).shortValue(), l);
  8. 2701             else if (arg instanceof Integer)
  9. 2702                 print(((Integer)arg).intValue(), l);
  10. 2703             else if (arg instanceof Long)
  11. 2704                 print(((Long)arg).longValue(), l);
  12. 2705             else if (arg instanceof BigInteger)
  13. 2706                 print(((BigInteger)arg), l);
  14. 2707             else
  15. 2708                 failConversion(c, arg);
  16. 2709         }
  17. 2710
复制代码
处理float
  1. 2711         private void printFloat(Object arg, Locale l) throws IOException {
  2. 2712             if (arg == null)
  3. 2713                 print("null");
  4. 2714             else if (arg instanceof Float)
  5. 2715                 print(((Float)arg).floatValue(), l);
  6. 2716             else if (arg instanceof Double)
  7. 2717                 print(((Double)arg).doubleValue(), l);
  8. 2718             else if (arg instanceof BigDecimal)
  9. 2719                 print(((BigDecimal)arg), l);
  10. 2720             else
  11. 2721                 failConversion(c, arg);
  12. 2722         }
复制代码
即是说,Java是hardcode了这部分显示,没有道理可言。
回复  

使用道具 举报

您需要登录后才可以回帖 登录 | FreeOZ用户注册

本版积分规则

小黑屋|手机版|Archiver|FreeOZ论坛

GMT+11, 6-3-2025 05:39 , Processed in 0.056789 second(s), 40 queries , Gzip On, Redis On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表