Java谜题畅读版之类谜题

谜题46:令人混淆的构造器案例

下面的程序打印出什么呢?甚至它是否是合法的呢?
public class Confusing {
    private Confusing(Object o) {
        System.out.println("Object");
    }
    private Confusing(double[] dArray) {
        System.out.println("double array");
    }
    public static void main(String[] args) {
        new Confusing(null);
    }
}
这类题有一个通用的解法, 即会调用最不会产生起义, 类型最精确的那个构造器.

谜题47:啊呀!我的猫变成狗了

下面的程序使用了一个Counter类来跟踪每一种家庭宠物叫唤的次数。那么该程序会打印出什么呢?
class Counter {
    private static int count = 0;
    public static final synchronized void increment() {
        count++;
    }
    public static final synchronized int getCount() {
        return count;
    }
}

class Dog extends Counter {
    public Dog() { }
    public void woof() { increment(); }
}

class Cat extends Counter {
    public Cat() { }
    public void meow() { increment(); }
}

public class Ruckus {
    public static void main(String[] args) {
        Dog dogs[] = { new Dog(), new Dog() };
        for (int i = 0; i < dogs.length; i++)
            dogs[i].woof();
        Cat cats[] = { new Cat(), new Cat(), new Cat() };
        for (int i = 0; i < cats.length; i++)
            cats[i].meow();
        System.out.print(Dog.getCount() + " woofs and ");
        System.out.println(Cat.getCount() + " meows");
    }
}
我们听到两声狗叫和三声猫叫——肯定是好一阵喧闹——因此,程序应该打印2 woofs and 3 meows,不是吗?不:它打印的是5 woofs and 5 meows。
问题在于Dog和Cat都从其共同的超类那里继承了count域,而count又是一个静态域。每一个静态域在声明它的类及其所有子类中共享一份单一的拷贝,因此Dog和Cat使用的是相同的count域。

谜题48:我所得到的都是静态的

下面的程序,会输出什么?
class Dog {
    public static void bark() {
        System.out.print("woof ");
    }
}

class Basenji extends Dog {
    public static void bark() {}
}

public class Bark {
    public static void main(String args[]) {
        Dog woofer = new Dog();
        Dog nipper = new Basenji();
        woofer.bark();
        nipper.bark();
    }
}
这个问题简单的说就是子类的静态方法"覆盖"了父类的静态方法,我打引号的意思是,其实没有子类的静态方法覆盖父类的静态方法一说,从根本上讲,静态方法是虚拟机的。
该程序输出的是woof woof. 即最终都是调用了Dog的方法,因为woofer和nipper都是Dog类型。该程序说明,静态方法通过类名来调用才靠谱。

谜题49:比生命更大

下面的程序说起来很简单,就是计算一下腰带尺寸beltSize,也就是CURRENT_YEAR - 1930,也就是今年和1930年之间差多少年。这个程序出了问题,是和初始化顺序有关,你能看出来吗?
public class Elvis {
    public static final Elvis INSTANCE = new Elvis();
    private final int beltSize;
    private static final int CURRENT_YEAR =
        Calendar.getInstance().get(Calendar.YEAR);
    private Elvis() {
        beltSize = CURRENT_YEAR - 1930;
    }    
    public int beltSize() {
        return beltSize;
    }
    public static void main(String[] args) {
        System.out.println("Elvis wears a size " +
                           INSTANCE.beltSize() + " belt.");
    }
}
再来回忆一下类的初始化顺序:父类静态变量和父类静态代码块—>子类静态变量和子类静态代码块—>父类非静态变量和父类非静态代码块—>父类构造方法—>子类非静态变量和子类非静态代码块—>子类构造方法。
其中要说明的是,对于静态成员,先他们都获得一个初始值,即0,null之类。然后调用<clinit>()执行类构造器,它包含静态成员的赋值语句和静态初始化块。静态成员的赋值语句和静态初始化块的执行顺序是他们声明的先后顺序。
对于非静态成员,他们也会在实例化的时候获得一个初始值,即0,null之类。然后调用<init>()执行实例构造器,它包含非静态成员赋值语句,非静态初始化块和构造函数的语句。非静态成员赋值语句,非静态初始化块和构造函数的执行顺序为: 构造函数排在最后,非静态成员的赋值语句和非静态初始化块按照声明的顺序。
这个程序输出-1930,自己分析原因吧。

谜题50:不是你的类型

本谜题要测试你对Java的两个最经典的操作符:instanceof和转型的理解程度。下面的三个程序每一个都会做些什么呢?
public class Type1 {
    public static void main(String[] args) {
        String s = null;
        System.out.println(s instanceof String);
    }
}

public class Type2 {
    public static void main(String[] args) {
        System.out.println(new Type2() instanceof String);
    }
}

public class Type3 {
    public static void main(String args[]) {
        Type3 t3 = (Type3) new Object();
    }
}
第一个程序很有现实意义,java规定,对null做instanceof都返回false,因为如果返回true,你下一步就可能真的去执行转型。
第二个程序也有现实意义,java规定,instanceof左操作数的类型和右边的类型应该必须是满足一方是另一方的子类。否则编译通不过。
第三个程序能通过编译,但是运行会报ClassCastException,暴漏的问题是,编译器无法在编译器确认Object这种根类型的实例不能转为其他类型。

谜题51:那个点是什么?

下面程序有两个类,第一个类用整数坐标来表示平面上的一个点,第二个类在此基础上添加了一点颜色。程序会打印出什么?
class Point {
    protected final int x, y;
    private final String name; // Cached at construction time
    Point(int x, int y) {
        this.x = x;
        this.y = y;
        name = makeName();
    }
    
    protected String makeName() {
        return "[" + x + "," + y + "]";
    }
    public final String toString() {
        return name;
    }
}

public class ColorPoint extends Point {
    private final String color;
    ColorPoint(int x, int y, String color) {
        super(x, y);
        this.color = color;
    }
    protected String makeName() {
       return super.makeName() + ":" + color;
    }
    public static void main(String[] args) {
        System.out.println(new ColorPoint(4, 2, "purple"));
    }
}
这个程序一眼看去,似乎应该打印出[4,2]:purple,但实际上打印的是[4,2]:null, 这个题和49题有相似之处,只是49关系到类的初始化顺序,而这个题关系到实例的初始化。
这个题说明,当父类的构造器调用了一个可能会被覆写的方法时,极有可能会出问题。

谜题52:合计数的玩笑

这个程序,简单的说就是算出从1到n的整数总和n(n+1)/2。它会打印出什么?
class Cache {
    static {
        initializeIfNecessary();
    }
    private static int sum;
    public static int getSum() {
        initializeIfNecessary();
        return sum;
    }
    
    private static boolean initialized = false;
    private static synchronized void initializeIfNecessary() {
        if (!initialized) {
            for (int i = 0; i < 100; i++)
                sum += i;
            initialized = true;
        }
    }
}
public class Client {
    public static void main(String[] args) {
        System.out.println(Cache.getSum());
    }
}
看起来这个程序打印出99*100/2=4950似乎没有什么问题,但是它实际上打印出了9900,刚好2倍。
这个题恰恰就考察了静态成员的赋值语句和静态初始化块的执行顺序问题。如同我在49题中说的那样,静态成员最初的时候都会获得一个默认的初始值,然后会执行<clinit>(),它包含了静态成员的赋值和静态初始化快。静态成员的赋值和静态初始化快是按照他们出现的顺序执行的。这样就导致了initialized最开始=false,执行静态初始化块孩子后=true,然后执行静态成员的赋值语句之后又变成false,sum的计算被执行了2次。

谜题53:按你的意愿行事

该题没意思,跳过。

谜题54:Null与Void

该题在前面出现过,也跳过。

谜题55:特创论

下面的程序中,Creature类有一个静态成员,可以跟踪该类创建了多少个实例。请问它输出什么?
public class Creator {
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++)
            Creature creature = new Creature();
        System.out.println(Creature.numCreated());
    }
}

class Creature {
    private static long numCreated = 0;
    public Creature() {
        numCreated++;
    }
    public static long numCreated() {
        return numCreated;
    }
}
该程序不能通过编译,出的问题可能你从来没有遇到过:Creature creature = new Creature();Java语言规范不允许一个本地变量声明语句作为一条语句在for、while或do循环中重复执行。
这个问题也好解决,把Creature creature = new Creature();放到花括号里,因为java有块作用域。还有就是干脆不需要声明变量,直接调用构造函数。
这个题目还有一个问题,就是它不是线程安全的。
Java谜题 Java谜题1——表达式谜题 谜题1:奇数性 谜题2:找零时刻 谜题3:长整除 谜题4:初级问题 谜题5:十六进制的趣事 谜题6:多重转型 谜题7:互换内容 谜题8:Dos Equis 谜题9:半斤 谜题10:八两 Java谜题2——字符谜题 谜题11:最后的笑声 谜题12:ABC 谜题13:畜牧场 谜题14:转义字符的溃败 谜题15:令人晕头转向的Hello 谜题16:行打印程序 谜题17:嗯? 谜题18:字符串奶酪 谜题19:漂亮的火花(块注释符) 谜题20:我的类是什么? 谜题21:我的类是什么?第2幕 谜题22:URL的愚弄 谜题23:不劳无获 Java谜题3——循环谜题 谜题24:尽情享受每一个字节 谜题25:无情的增量操作 谜题26:在循环中 谜题27:变幻莫测的i值 谜题28:循环者 谜题29:循环者的新娘 谜题30:循环者的爱子 谜题31:循环者的鬼魂 谜题32:循环者的诅咒 谜题33:循环者遇到了狼人 谜题34:被计数击倒了 谜题35:一分钟又一分钟 Java谜题4——异常谜题 谜题36:优柔寡断 谜题37:极端不可思议 谜题38:不受欢迎的宾客 谜题39:您好,再见 谜题40:不情愿的构造器 谜题41:域和流 谜题42:异常为循环而抛 谜题43:异常地危险 谜题44:切掉类 谜题45:令人疲惫不堪的测验 Java谜题5——类谜题 谜题46:令人混淆的构造器案例 谜题47:啊呀!我的猫变成狗了 谜题48:我所得到的都是静态的 谜题49:比生命更大 谜题50:不是你的类型 谜题51:那个点是什么? 谜题52:合计数的玩笑 谜题53:按你的意愿行事 谜题54:Null与Void 谜题55:特创论 Java谜题6——库谜题 谜题56:大问题 谜题57:名字里有什么? 谜题58:产生它的散列码 谜题59:什么是差? 谜题60:一行的方法 谜题61:日期游戏 谜题62:名字游戏 谜题63:更多同样的问题 谜题64:按余数编组 谜题65:一种疑似排序的惊人传奇 Java谜题7——更多的类谜题 谜题66:一件私事 谜题67:对字符串上瘾 谜题68:灰色的阴影 谜题69:黑色的渐隐 谜题70:一揽子交易 谜题71:进口税 谜题72:终极危难 谜题73:你的隐私正在公开 谜题74:同一性的危机 谜题75:头还是尾? 名字重用的术语表 Java谜题8——更多的库谜题 谜题76:乒乓 谜题77:搞乱锁的妖怪 谜题78:反射的污染 谜题79:这是狗的生活 谜题80:更深层的反射 谜题81:烧焦(字符化)到无法识别 谜题82:啤酒爆炸 谜题83:诵困难者的一神论 谜题84:被粗暴地中断 谜题85:惰性初始化 Java谜题9——高级谜题 谜题86:有毒的括号垃圾 谜题87:紧张的关系 谜题88:原生类型的处理 谜题89:泛型迷药 谜题90:荒谬痛苦的超类 谜题91:序列杀手 谜题92:双绞线 谜题93:类的战争 谜题94:迷失在混乱中 谜题95:只是些甜点 ********************* Chapter 1. Introduction Chapter 2. Expressive Puzzlers Puzzle 1: Oddity Puzzle 2: Time for a Change Puzzle 3: Long Division Puzzle 4: It's Elementary Puzzle 5: The Joy of Hex Puzzle 6: Multicast Puzzle 7: Swap Meat Puzzle 8: Dos Equis Puzzle 9: Tweedledum Puzzle 10: Tweedledee Chapter 3. Puzzlers with Character Puzzle 11: The Last Laugh Puzzle 12: ABC Puzzle 13: Animal Farm Puzzle 14: Escape Rout Puzzle 15: Hello Whirled Puzzle 16: Line Printer Puzzle 17: Huh? Puzzle 18: String Cheese Puzzle 19: Classy Fire Puzzle 20: What's My Class? Puzzle 21: What's My Class, Take 2 Puzzle 22: Dupe of URL Puzzle 23: No Pain, No Gain Chapter 4. Loopy Puzzlers Puzzle 24: A Big Delight in Every Byte Puzzle 25: Inclement Increment Puzzle 26: In the Loop Puzzle 27: Shifty i's Puzzle 28: Looper Puzzle 29: Bride of Looper Puzzle 30: Son of Looper Puzzle 31: Ghost of Looper Puzzle 32: Curse of Looper Puzzle 33: Looper Meets the Wolfman Puzzle 34: Down for the Count Puzzle 35: Minute by Minute Chapter 5. Exceptional Puzzlers Puzzle 36: Indecision Puzzle 37: Exceptionally Arcane Puzzle 38: The Unwelcome Guest Puzzle 39: Hello, Goodbye Puzzle 40: The Reluctant Constructor Puzzle 41: Field and Stream Puzzle 42: Thrown for a Loop Puzzle 43: Exceptionally Unsafe Puzzle 44: Cutting Class Puzzle 45: Exhausting Workout Chapter 6. Classy Puzzlers Puzzle 46: The Case of the Confusing Constructor Puzzle 47: Well, Dog My Cats! Puzzle 48: All I Get Is Static Puzzle 49: Larger Than Life Puzzle 50: Not Your Type Puzzle 51: What's the Point? Puzzle 52: Sum Fun Puzzle 53: Do Your Thing Puzzle 54: Null and Void Puzzle 55: Creationism Chapter 7. Library Puzzlers Puzzle 56: Big Problem Puzzle 57: What's in a Name? Puzzle 58: Making a Hash of It Puzzle 59: What's the Difference? Puzzle 60: One-Liners Puzzle 61: The Dating Game Puzzle 62: The Name Game Puzzle 63: More of the Same Puzzle 64: The Mod Squad Puzzle 65: A Strange Saga of a Suspicious Sort Chapter 8. Classier Puzzlers Puzzle 66: A Private Matter Puzzle 67: All Strung Out Puzzle 68: Shades of Gray Puzzle 69: Fade to Black Puzzle 70: Package Deal Puzzle 71: Import Duty Puzzle 72: Final Jeopardy Puzzle 73: Your Privates Are Showing Puzzle 74: Identity Crisis Puzzle 75: Heads or Tails? A Glossary of Name Reuse Chapter 9. More Library Puzzlers Puzzle 76: Ping Pong Puzzle 77: The Lock Mess Monster Puzzle 78: Reflection Infection Puzzle 79: It's a Dog's Life Puzzle 80: Further Reflection Puzzle 81: Charred Beyond Recognition Puzzle 82: Beer Blast Puzzle 83: Dyslexic Monotheism Puzzle 84: Rudely Interrupted Puzzle 85: Lazy Initialization Chapter 10. Advanced Puzzlers Puzzle 86: Poison-Paren Litter Puzzle 87: Strained Relations Puzzle 88: Raw Deal Puzzle 89: Generic Drugs Puzzle 90: It's Absurd, It's a Pain, It's Superclass! Puzzle 91: Serial Killer Puzzle 92: Twisted Pair Puzzle 93: Class Warfare Puzzle 94: Lost in the Shuffle Puzzle 95: Just Desserts Appendix A. Catalog of Traps and Pitfalls Section 1. Lexical Issues Section 2. Integer Arithmetic Section 3. Floating-Point Arithmetic Section 4. Expression Evaluation Section 5. Flow of Control Section 6. Class Initialization Section 7. Instance Creation and Destruction Section 8. Other Class- and Instance-Related Topics Section 9. Name Reuse Section 10. Strings Section 11. I/O Section 12. Threads Section 13. Reflection Section 14. Serialization Section 15. Other Libraries Appendix B. Notes on the Illusions Ambiguous Figures Impossible Figures Geometrical Illusions: Size Geometrical Illusions: Direction Subjective Contours Anomalous Motion Illusions Illusions of Lightness Compound Illusions
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值