FreeOZ论坛

标题: 茴字的四种写法之Java的小秘密 [打印本页]

作者: key    时间: 23-6-2009 21:16
标题: 茴字的四种写法之Java的小秘密
下面是一系列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 编辑 ]
作者: coredump    时间: 23-6-2009 21:31
http://yinyunqiao.blogspot.com/2007/11/blog-post_05.html  
作者: key    时间: 23-6-2009 22:15
标题: 继续茴字的四种写法: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 编辑 ]
作者: key    时间: 23-6-2009 22:30
标题: 茴字四种写法三: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 编辑 ]
作者: key    时间: 23-6-2009 23:43
标题: 茴字四种写法四: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. }
复制代码

作者: key    时间: 24-6-2009 00:23
标题: 茴字的四种写法五: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 编辑 ]
作者: key    时间: 24-6-2009 00:30
标题: 茴字四种写法五: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. }
复制代码

作者: key    时间: 24-6-2009 08:56
标题: 茴字四种写法六: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. }
复制代码

作者: someonehappy    时间: 24-6-2009 10:33
what's the difference between floor 3 and 4?
作者: key    时间: 24-6-2009 14:53
原帖由 someonehappy 于 24-6-2009 10:33 发表
what's the difference between floor 3 and 4?


贴错程序了,hoho~
作者: key    时间: 24-6-2009 15:34
标题: 茴字四种写法之七: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;
复制代码
上面哪些语句不合法?
作者: formatc    时间: 24-6-2009 22:51
真高深的~~~~~~~~~~~~~`
作者: key    时间: 25-6-2009 10:06
标题: 茴字四种写法之八: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. }
复制代码

作者: key    时间: 25-6-2009 10:08
标题: 茴字四种写法九: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 }
复制代码

作者: key    时间: 25-6-2009 10:21
标题: 茴字四种写法之十: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 }
复制代码

作者: gx043228    时间: 26-6-2009 00:11
牛比,我不想programming...
作者: key    时间: 26-6-2009 10:40
标题: 茴字的四种写法之十一: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. }
复制代码

作者: key    时间: 26-6-2009 10:52
标题: 茴字的四种写法之十二: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. }
复制代码

作者: key    时间: 26-6-2009 12:09
标题: 茴字四种写法之十三: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
复制代码

作者: key    时间: 26-6-2009 22:23
标题: 茴字四种写法之十四:神奇的字符
看下面的程序,试讨论它的输出:
  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 }
复制代码

作者: key    时间: 28-6-2009 19:24
标题: 茴字四种写法之十五:当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 }
复制代码

作者: key    时间: 28-6-2009 23:32
标题: 茴字四种写法之十六: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. }
复制代码

作者: key    时间: 29-6-2009 09:08
标题: 茴字四种写法之十七: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 }
复制代码

作者: key    时间: 29-6-2009 09:11
原帖由 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 编辑 ]
作者: key    时间: 29-6-2009 09:34
标题: 为什么会这样?
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论坛 (https://www.freeoz.org/bbs/) Powered by Discuz! X3.2