Java陷阱(五)
来源:互联网 发布:手机淘宝如何买东西 编辑:程序博客网 时间:2024/05/22 17:36
问题:令人混淆的构造器
代码:
/** * 令人混淆的构造器 * @authorLiangGzone */public class Confusing { publicConfusing(Object obj){ System.out.println("Object"); } publicConfusing(String str){ System.out.println("String"); } publicstatic void main(String[] args){ newConfusing(null); }}分析:Java的重载解析过程可以分为两个阶段。第一阶段,选取所有可获得并且可应用的方法或构造器。第二阶段,在第一阶段选择的方法或构造器中选取最精确的一个。
建议:想要强制要求编译器选择一个精确的重载版本,需要将实参转型为形参所声明的类型。重载版本的解析可能会产生混淆,应该尽可能避免重载。如果确定进行了重载 ,请保证所有的重载版本所接受的参数类型都是互不兼容的。
问题:狸猫变犬子
代码:
/** *狸猫变犬子 * @authorLiangGzone */class Counter{ privatestatic int count; publicstatic void increment(){count++;} publicstatic int getCount(){return count;}}class Dog extends Counter{ publicvoid woof(){increment();}}class Cat extends Counter{ publicvoid meow(){increment();}}public class Ruckus { publicstatic void main(String[] args){ Dogdog = newDog(); dog.woof(); Catcat = newCat(); cat.meow(); System.out.println(dog.getCount()+"woof"); System.out.println(cat.getCount()+"meow"); }}分析:静态字段由声明它的类及其子类所共享。
建议:如果需要让每一个子类都具有某个单独副本,那么必须在每一个子类中声明一个单独的静态字段。
问题:我所得到的都是静态的
代码:
/** *我所得到的都是静态的 * @authorLiangGzone * @version2013.04.02 */class Car{ publicstatic void bark(){ System.out.println("Dodo"); }}class SubCar extends Car{ publicstatic void bark(){}}public class Bark { publicstatic void main(String[] args){ Carcar = newCar(); Carsubcar = newSubCar(); car.bark(); subcar.bark(); }}分析:静态方法是不能被覆写的,它们只能被隐藏。
修改:
①类名.方法名:SubCar.bark();
②删掉static
问题:不是你的类型
代码:
/** *不是你的类型 * @authorLiangGzone */public class Type { publicstatic void main(String[] args){ Strings = null; System.out.println(sinstanceofString); }}分析:instanceof操作符被定义为在做操作数为null时返回false。
问题:不是你的类型(续)
代码:
/** *不是你的类型 * @authorLiangGzone */public class Type2 { publicstatic void main(String[] args){ System.out.println(newType() instanceof String); }}分析:错误。如果两个操作数的类型都是类,其中一个必须是另一个的子类型。
问题:特创论
代码:
/** *特创论 * @authorLiangGzone */public class Creator { publicstatic void main(String[] args){ for(int i = 0; i < 100; i++) { Creaturecreature = newCreature(); } System.out.println(Creature.getNum()); }}class Creature{ privatestatic long num = 0; publicCreature(){ num++; } publicstatic long getNum(){ returnnum; }}建议:
①在使用一个变量来对实例的创建进行计数时,要使用long类型而不是int类型的变量,以防止溢出。
②要注意,如果多线程可以并行创建对象,那么递增计数器的代码和读取计数器的代码都应该被同步。可以利用synchronized。如果你使用的是5.0或更新的版本,你可以使用一个AtomicLong实例,它可以在面临并发时绕过对同步的需要。允许那些处理基于数字类的工具和实用工具进行统一访问。
阅读链接:
Java陷阱(一)
Java陷阱(二)
Java陷阱(三)
Java陷阱(四)
Java陷阱(五)
Java陷阱(六)
- Java陷阱(五)
- Java陷阱(二)
- Java陷阱(三)
- Java陷阱(一)
- Java陷阱(四)
- Java陷阱(六)
- C陷阱与缺陷(五)库函数
- 小心笔试中的小陷阱(五)
- 读《C陷阱和缺陷》(五)
- C陷阱与缺陷(五)
- 读书笔记--C陷阱与缺陷(五)
- Java编程思想学习心得(五)自动递增和递减操作符的陷阱
- Java 陷阱
- java陷阱
- 程序员的五大陷阱
- 程序员的五大陷阱
- Java容器(十):subList的陷阱
- Java面试中的陷阱
- ORACLE 视图
- Jsp两种注释方式的比较。
- webView读取数据----乱码解决
- Calendar类使用实例
- 单例模式
- Java陷阱(五)
- iphone push notification 消息推送(转)
- FreeMarker 基本指令
- js表单验证控制代码大全
- MT4编程实例:在欧元图上显示英磅的RSI指标
- 常用uboot命令
- css代码缩写规范
- IDA 基本配置
- 使Android的system分区可写及安装apk到system/app