类之谜总结

1.方法重载规定

分析:

JAVA重载解析过程分为2步:

(1)根据实参选取所有可应用的。

(2)根据形参选取最精确的。(并没有使用实参)

比如:

如果fun(Object o)和fun(double[]b)都是可应用的,则double[]的每个对象都是Object类型的,因此double[]比Object更精确。

public class PuzzleDemo46{
	private PuzzleDemo46(Object o){
		System.out.println("Object"); 
	}
	private PuzzleDemo46(double[]darr){
		System.out.println("double array"); 
	}
	public static void main(String args[]){
		new PuzzleDemo46(null);
	}
}


2.类中的static属性的规定

每个静态的属性都在声明他的类和所有的子类中保持一个副本。

class Cat{
	private static int count = 0;
	public Cat(){
		
	}
	public void meow(){
		count++;
	}
	public static int getCount(){
		return count;
	}
}
class Dog{
	private static int count = 0;
	public Dog(){
		
	}
	public void woof(){
		count++;
	}
	public static int getCount(){
		return count;
	}
}
public class PuzzleDemo47{
	public static void main(String args[]){
		Cat c[] = {new Cat(),new Cat()};
		Dog d[] = {new Dog(),new Dog(),new Dog()};
		for(Cat e1:c){
			e1.meow();
		}
		for(Dog d1:d){
			d1.woof();
		}
		System.out.println("Cat:" + Cat.getCount());
		System.out.println("Dog:" + Dog.getCount()); 
	}
}


3.静态方法的(非多态性)

静态方法调用不是动态的,因此如果调用一个静态方法,则在编译器执行期已经确定。

比如:Person p = new Student();        p.say();    如果say是静态方法,则调用的是Person类的静态方法。

比如:(Person)null.say();调用的是Person.say(),null不起任何作用。

总结:调用静态方法时,必须使用类来调用,而不是用类的实例进行调用。

 

class Dog{
	public static void bark(){
		System.out.println("woof	"); 
	}
}
class Basenji extends Dog{
	public static void bark(){
	
	}
}
public class PuzzleDemo48{
	public static void main(String args[]){
		Dog.bark();
		Basenji.bark();
	}
}
示例2:

public class PuzzleDemo54{
	public static void main(String args[]){
		((PuzzleDemo54)null).greet();
		greet();
	}
	public static void greet(){
		System.out.println("Hello world!"); 
	}
}


4.类的初始化

类初始化顺序:

(1)把静态字段设置为默认值。

(2)静态字段初始器按照其在源代码中出现顺序执行,比如static属性、final static属性、static语句块等,因此会出现调用还没有被初始器初始化的静态字段,尽量把属性都放在类的前面。

(3)在执行类的方法前,必须对类进行初始化。

积极初始化和延迟初始化:不要同时使用两者。

当在程序每次执行都会用到时,则使用积极初始化。

当不是每次执行都会用到时,则使用延迟初始化。

结论:类的初始化顺序显得重要时,请特别当心!

比较两个程序:

import java.util.*;
public class PuzzleDemo49_2{
	private static final PuzzleDemo49_2 INSTANCE = new PuzzleDemo49_2();
	private final int beltSize;
	private final int CURRENT_YEAR = Calendar.getInstance().get(Calendar.YEAR);
	private PuzzleDemo49_2(){
		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."); 
	}
}
//CURRENT_YEAR is final ,so not static 

import java.util.*;
public class PuzzleDemo49{
	private static final PuzzleDemo49 INSTANCE = new PuzzleDemo49();
	private final int beltSize;
	private static final int CURRENT_YEAR = Calendar.getInstance().get(Calendar.YEAR);
	private PuzzleDemo49(){
		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."); 
	}
}


示例2:

class Cache{
	private static boolean initialized = false;
	static{
		initializeIfNecessary();
	}
	private static int sum;
	public static int getSum(){
		initializeIfNecessary();
		return sum;
	}
	
	private static synchronized void initializeIfNecessary(){
		if(!initialized){
			for(int i=0;i<100;i++){
				sum +=i;
			}
			initialized = true;	
		}
	}
}
public class PuzzleDemo52{
	public static void main(String args[]){
		System.out.println(Cache.getSum()); 
	}
}


5.instanceof的两条规定

(1)如果instanceof的左操作数是null,则返回false;

(2)如果两个操作数的类型都是类,则instanceof的左右操作数一定是子类或父类关系;

public class PuzzleDemo50{
	public static void main(String args[]){
		System.out.println("null instanceof String:"+(null instanceof String)); 
		System.out.println("int instanceof String:"+(new Integer(1) instanceof String));	//不可转换
	}
}


6.忠告:千万不要在构造器中调用子类覆写的方法,否则默认会调用子类覆写的方法。

public class PuzzleDemo51 extends Point{
	private final String color;
	PuzzleDemo51(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 PuzzleDemo51(4,2,"Puzzle")); 
	}
}
class Point{
	private final int x,y;
	private String name;
	Point(int x,int y){
		this.x = x;
		this.y = y;
	}
	protected String makeName(){
		return "["+x+","+y+"]";
	}
	public final String toString(){
		name = this.makeName();//延迟初始化
		return name;
	}
}


7.局部变量声明的规定

JAVA语言规范:不允许一个局部变量声明语句作为一条语句在for、while、do循环中重复执行。

因此一个局部变量声明语句只能出现在一个语句块中。

 

public class PuzzleDemo55{
	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(){
		synchronized(Creature.class){
			numCreated++;
		}
	}
	public static long numCreated(){
		return numCreated;
	}
}

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值