面对对象编程第四节

1.Java包装类

JDK1.50之后支持所谓的自动转换器,自动转换器就是直接把一个基本类型值赋给一个包装类实例,在这种情况下可能会出现依一些特别的情形:

Integer ina=2;
		Integer inb=2;
		System.out.println("两个2自动装后是否相等"+(ina==inb));//输出true
		Integer biga=128;
		Integer bigb=128;
		System.out.println("两个128自动装箱后是否相等"+(biga==bigb));//输出false
		Integer midA=127;
		Integer midB=127;
		System.out.println("两个127自动装箱后是否相等"+(midA==midB));//输出true
		Integer SmillA=-129;
		Integer SmillB=-129;
		System.out.println("两个-129自动装箱后是否相等"+(SmillA==SmillB));输出false

为什么会出现上文中的结果:

首先我们查看其中Integer的源码

static final int high;
        static final Integer cache[];

        static {
            final int low = -128;

            // high value may be configured by property
            int h = 127;
            if (integerCacheHighPropValue != null) {
                // Use Long.decode here to avoid invoking methods that
                // require Integer's autoboxing cache to be initialized
                int i = Long.decode(integerCacheHighPropValue).intValue();
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - -low);
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }
化为简单的代码:

//Java的Integer类的设计,查看Java系统中java.lang.Integer类的源代码
	static final Integer[] cache=new Integer[-(-128)+127+1];
	static{
		for(int i=0;i<cache.length;i++){
			cache[i]=new Integer(i-128);
		}
		{
			for(int i=0;i<cache.length;i++){
				System.out.println(cache[i]);
			}
		}
	}
从上面的代码的可以看出,系统把一个-128~127之间的整数自动装箱成为Integer实例,并放入到一个名为cache的数组中缓存起来。如果以后把一个-128~127之间的整数自动装箱成一个Integer实例时,实际上是直接指向对应的数组元素,因此-128~127之间的同一个整数自动装箱成Integer实例时,永远都是引用cache数组的同一个数组元素,所以他们全部相等;但每次把一个不在-128~127范围内的整数自动装箱成Integer实例时,系统总是重新创建一个Integer实例,所以出现程序运行的结果。

2.to.String()方法,

class Person{
	private String name;
	public Person(String name){
		this.name=name;
	}
}
public class PrintObject {
	public static void main(String[] args){
		//创建一个Person对象,将之赋给p变量
		Person p=new Person("孙悟空");
		//打印P变量所引用的对象
		System.out.println(p);
		System.out.println(p.toString());
	}
}
输出结果:

Day04.Person@55f33675
Day04.Person@55f33675

输出的为对象的引用,也就是对象的地址

输出是一个类对象时候,会调用这个对象的to.string()方法,这个方法有些类是覆盖了的,比如说String,Integer,你自己写的类没有覆盖这个方法的话就继承Object类的这个方法,Object中to.String()方法时这样的

getClass().getName()+"@"+Integer.toHaxString(hashCode)
后面跟的这个数的哈希码,如果你希望输出出来的是你所需要的格式,那么就需要覆盖to.String方法。

覆盖toString的方法

class Apple{
	private String color;
	private double weight;
	public Apple(){
		
	}
	//提供有参数的构造器
	public Apple(String color,double weight){
		this.color=color;
		this.weight=weight;
	}
	public void setColor(String color){
		this.color=color;
	}
	public String getColor(){
		return this.color;
	}
	public void setWeight(double weight){
		this.weight=weight;
	}
	public double getWeight(){
		return this.weight;
	}
	public String toString(){
		return "一个苹果,颜色是:"+this.color+",重量是"+this.weight;
	}
}
public class ToStringTest {
	public static void main(String[] args){
		Apple a=new Apple("red",5.68);
		//打印Apple对象
		System.out.println(a);
	}
}
重写equals的方法:

class Person{
	private String idStr;
	private String name;
	public Person(){}
	public Person(String name,String idStr){
		this.name=name;
		this.idStr=idStr;
	}
	public void getName(String name){
		this.name=name;
	}
	public String setName(){
		return this.name;
	}
	public void setIdStr(String idStr){
		this.idStr=idStr;
	}
	public String getIdStr(){
		return this.idStr;
	}
	public boolean equals(Object obj){
		//如果两个对象为同一个对象
		//如果另一个对象和当前对象引用都一样,那么肯定是同一个对象实例,返回true
		if(this==obj){
			return true;
		}
		//只有当obj是Person对象
		if(obj!=null&&obj.getClass()==Person.class){
			Person personObj=(Person)obj;	
			//只有obj是Person对象
			if(this.getIdStr().equals(personObj.getIdStr())){
				//并且当前对象的idStr与obj对象的idStr相等时才可以判断两个对象相等
				return true;
			}
		}
		return false;
	}
}
public class OverrideEqualsRight {
	public static void main(String[] args){
		Person p1=new Person("孙悟空","3123124312");
		Person p2=new Person("孙行者","3123124312");
		Person p3=new Person("孙悟饭","1243242352");
		//p1和p2的idStr相等,所以输出true
		System.out.println("p1和p2是否相等"+p1.equals(p2));
		//p2和p3的idStr不相等,所以输出false
		System.out.println("p2和p3是否相等"+p2.equals(p3));
	}
}
通常而言,正确地重写equals()方法应该满足下列条件

1)自反性:对任意x,x.equals(x)一定返回true

2)对称性:对任意x和y,如果y.equals(x)返回true,则x.equals(y)也返回true

3)传递性:对任意x,y,z如果x.equals(y)返回true,y.equals(z)返回true,则x.equals(y)也返回true

4)一致性:对任意x和y,如果对象用用于等价比较的信息没有改变,那么无论调用x.equals(y)多少次,返回的结果应该保持一致,要么一直是true,要么一直是false;

5)任何不是null的x,x.equals(null)一定返回false;

猜你喜欢

转载自blog.csdn.net/xiao_chainiao/article/details/75277837