java解惑2-字符谜题

来源:互联网 发布:apache压缩包怎么安装 编辑:程序博客网 时间:2024/06/05 00:38

谜题11:最后的笑声

public class LastLaugh{    public static void main(String[] args){        System.out.print("H"+"a");        System.out.print('H'+'a');    }}
                  题目:  Ha169  注(a: 97 , A : 65 ,0: 48)

                  原因:问题在于'H'和'a'是字符型字面常量,因为这两个操作数都不是字符串类型的,所以+ 操作符执行的是加
                              法而不是字符串连接。
                  解决办法:使用字符串连接操作符使用格外小心。+ 操作符当且仅当它的操作数中至少有一个是String类型时,
                               才会执行字符串连接操作;否则,它执行的就是加法。如果要连接的没有一个数值是字符串类型的,那
                                么你可以有几种选择:

  • 预置一个空字符串;
  • 将第一个数值用String.valueOf显式地转换成一个字符串;
  • 使用一个字符串缓冲区;
  • 或者如果你使用的JDK 5.0,可以用printf方法。

谜题12:ABC

public class ABC{    public static void main(String[] args){        String letters = "ABC";        char[] numbers = {'1', '2', '3'};        System.out.println(letters + " easy as " + numbers);    }}
题目: ABC easy as [C@16f0472
原因: 数组是从Object那里继承的toString方法[JLS 10.7],规范中描述到:“返回一个字符串, 它包含了该对象所属类的名字,'@'符号,以及表示对象散列码的一个无符号十六进制整数” [Java-API]。

                  解决办法: char数组不是字符串。要想将一个char数组转换成一个字符串,就要调用String.valueOf
                                (char[])方法。某些类库中的方法提供了对char数组的类似字符串的支持,通常是提供一个Object
                                版本的重载方法和一个char[]版本的重载方法,而之后后者才能产生我们想要的行为。 PI]

谜题13:畜牧场

public class AnimalFarm{    public static void main(String[] args){        final String pig = "length: 10";        final String dog = "length: " + pig.length();        System.out. println("Animals are equal: "                            + pig == dog);    }}
                  题目:Animal are equal: true
                  原因:同13


谜题14:转义字符的溃败

public class EscapeRout{    public static void main(String[] args){        // \u0022 是双引号的Unicode转义字符        System.out.println("a\u0022.length()+\u0022b".length());    }}
                    题目:输出2
                    原因:Java对在字符串字面常量中的Unicode转义字符没有提供任何特殊处理。
                                编译器在将程序解析成各种符号之前,先将Unicode转义字符转换成为它们所表示的字符[JLS3.2]。
                                 因此,程序中的第一个Unicode转义字符将作为一个单字符字符串字面常量("a")的结束引号,
                                 而第二个Unicode转义字符将作为另一个单字符字符串字面常量("b")的开始引号。程序打印的
                                是表达式"a".length()+"b".length(),即2。

谜题15:令人晕头转向的Hello

/** * Generated by the IBM IDL-to-Java compiler, version 1.0 * from F:\TestRoot\apps\a1\units\include\PolicyHome.idl * Wednesday, June 17, 1998 6:44:40 o’clock AM GMT+00:00 */public class Test{    public static void main(String[] args){        System.out.print("Hell");        System.out.println("o world");    }}
                    题目: 编译不过

                    原因:问题在于注释的第三行,它包含了字符\units。这些字符以反斜杠(\)以及紧跟着的字母u开头的,
                                而它(\u)表示的是一个Unicode转义字符的开始。遗憾的是,这些字符后面没有紧跟四个十六进制
                                的数字,因此,这个Unicode转义字符是病构的,而编译器则被要求拒绝该程序。Unicode转义字符
                                必须是良构的,即使是出现在注释中也是如此。

谜题16:行打印程序

public class LinePrinter{    public static void main(String[] args){    // Note: \u000A is Unicode representation of linefeed (LF)         char c = 0x000A;        System.out.println(c);       }}
                      题目:

                      原因:在Windows平台上,它是CR字符(回车)和紧随其后的LF字符(换行)组成的,
                                  而在UNIX平台上,通常单独的LF字符被当作换行字符来引用。
 

谜题17:嗯?

\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0020\u0020\u0020\u0063\u006c\u0061\u0073\u0073\u0020\u0055\u0067\u006c\u0079\u007b\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0073\u0074\u0061\u0074\u0069\u0063\u0076\u006f\u0069\u0064\u0020\u006d\u0061\u0069\u006e\u0028\u0053\u0074\u0072\u0069\u006e\u0067\u005b\u005d\u0020\u0020\u0020\u0020\u0020\u0020\u0061\u0072\u0067\u0073\u0029\u007b\u0053\u0079\u0073\u0074\u0065\u006d\u002e\u006f\u0075\u0074\u002e\u0070\u0072\u0069\u006e\u0074\u006c\u006e\u0028\u0020\u0022\u0048\u0065\u006c\u006c\u006f\u0020\u0077\u0022\u002b\u0022\u006f\u0072\u006c\u0064\u0022\u0029\u003b\u007d\u007d
                      略

谜题18:字符串奶酪   

public class StringCheese {    public static void main(String[] args) {        byte bytes[] = new byte[256];        for (int i = 0; i < 256; i++)             bytes[i] = (byte)i;        String str = new String(bytes);        for (int i = 0, n = str.length(); i < n; i++)             System.out.println((int)str.charAt(i) + " ");    }}
                       原因:到底什么是字符集?从技术角度上讲,它是“被编码的字符集合和字符编码模式的结合物”[Java-API]。
                                   换句话说,字符集是一个包,包含了字符、表示字符的数字编码以及在字符编码序列和字节序列之间
                                  来回转换的方式。转换模式在字符集之间存在着很大的区别:某些是在字符和字节之间做一对一的映射
                                  ,但是大多数都不是这样。ISO-8859-1是唯一能够让该程序按顺序打印从0到255的整数的缺省字符集,
                                  它更为大家所熟知的名字是Latin-1[ISO-8859-1]。

                        解决:String str = new String(bytes, "ISO-8859-1");

        

谜题19:漂亮的火花

public class Classifier {    public static void main(String[] args) {        System.out.println(             classify('n') + classify('+') + classify('2'));    }    static String classify(char ch) {        if ("0123456789".indexOf(ch) >= 0)             return "NUMERAL ";        if ("abcdefghijklmnopqrstuvwxyz".indexOf(ch) >= 0)             return "LETTER ";        /* (Operators not supported yet)            if ("+-*/&|!=" >= 0)                 return "OPERATOR ";        */        return "UNKNOWN";    }}
                             题目:无法编译

                            原因: 注释代码

谜题20:我的类是什么? 

package com.javapuzzlers;public class Me {    public static void main(String[] args){        System.out.println(             Me.class.getName().                replaceAll(".","/") + ".class");    }}
                             题目:

                             解决办法 :java.util.regex.Pattern.quote。它接受一个字符串作为参数,并可以添加必需的转义字符,
                                                  它将返回一个正则表达式字符串,该字符串将精确匹配输入的字符串。下面是使用该方法
                                                  之后的程序:

package com.javapuzzlers;import java.util.regex.Pattern;public class Me {    public staticvoid main(String[] args){       System.out.println(Me.class.getName().                       replaceAll(Pattern.quote("."),"/")+ ".class");    }}

谜题21:我的类是什么?II

package com.javapuzzlers;import java.io.File;public class MeToo {    public static void main(String[] args){        System.out.println(MeToo.class.getName().replaceAll("\\.", File.separator) + ".class");    }}
                               题目:当你在Windows上运行该程序时,替代字符串是单独的一个反斜杠,它是无效的。不可否认
                               原因:

                               解决办法:

System.out.println(MeToo.class.getName().replaceAll("\\.", Matcher.quoteReplacement(File.separator))+ ".class");

System.out.println(MeToo.class.getName().replace(".",File.separator) + ".class");

谜题22:URL的愚弄

public class BrowserTest {    public static void main(String[] args) {        System.out.print("iexplore:");        http://www.google.com;        System.out.println(":maximize");    }}
                              题目:打印iexplore::maximize。
                              原因:在Java中很少需要标号,这多亏了Java没有goto语句。在本谜题中所引用的“Java编程语言中很少被
                                          人了解的特性”实际上就是你可以在任何语句前面放置标号。这个程序标注了一个表达式语句,它是
                                         合法的,但是却没什么用处。 

                              注:
提醒你,如果你真的想要使用标号,那么应该用一种更合理的方式来格式化程序:public class BrowserTest {    public staticvoid main(String[] args) {        System.out.print("iexplore:");    http:      //www.google.com;       System.out.println(":maximize");    }}

谜题23:不劳无获

import java.util.Random;public class Rhymes {   private static Random rnd = new Random();   public static void main(String[] args) {      StringBuffer word = null;      switch(rnd.nextInt(2)) {          case 1:  word = new StringBuffer('P');          case 2:  word = new StringBuffer('G');          default: word = new StringBuffer('M');      }      word.append('a');      word.append('i');      word.append('n');      System.out.println(word);   }}
                               题目: 永远输出ain

                               原因: 第一个bug:是所选取的随机数使得switch语句只能到达其三种情况中的两种。

                                            第二个bug:bug是在不同的情况(case)中没有任何break语句。不论switch
                                                                 表达式为何值,该程序都将执行其相对应的case以及所有后续的case[JLS14.11]。

                                             第三个bug:也是最微妙的一个bug是表达式newStringBuffer('M'),你可能对StringBuffer(char)
                                                                   构造器并不熟悉,这很容易解释:它压根就不存在。StringBuffer有一个无参数的构
                                                                  造器,一个接受一个String作为字符串缓冲区初始内容的构造器,以及一个接受一个
                                                                   int作为缓冲区初始容量的构造器。在本例中,编译器会选择接受int的构造器,通过
                                                                  拓宽原始类型转换把字符数值'M'转换为一个int数值77[JLS 5.1.2]。换句话说,
                                                                   new StringBuffer('M')返回的是一个具有初始容量77的空的字符串缓冲区。该程序余
                                                                 下的部分将字符a、i和n添加到了这个空字符串缓冲区中,并打印出该字符串缓冲区那
                                                                   总是ain的内容。

                              解决方案:

import java.util.Random;public class Rhymes2 {   private static Random rnd = new Random();   public static void main(String[] args) {      System.out.println("PGM".charAt(rnd.nextInt(3)) + "ain");   }}


 


原创粉丝点击