包装类和object类

object类

1.Java.lang.object
2.所有类的超类
3.没有声明extends默认父类是Java.lang.object
自己可以创建一个类并且实列化对象试一下

对象.getClass().getSuperclass

显示出来就是:class Java.lang.object
4.object类的功能属性方法就子类也可以用通用
5.object有一个空构造器,所有类调用的时候都会调用这个构造器

方法:
(1)clone()
api:create and return a cope of this object
创建一个并返回你当前对象
Object本身不实现接口Cloneable,所以调用一个对象的类是Object将导致在运行时抛出异常的clone方法
如果对象的类不支持 Cloneable接口。子类重写 clone方法也抛出该异常表示实例无法克隆
CloneNotSupportedException
看一个实际列子:
比如:
假设我们创建了一个类Animal

//创建一个名字叫花花的动物
Animal a1 = new Animal("花花");
//我们clone一个动物,并且为它起一个新的名字叫毛毛,这里需要抛出异常我就不写了
Animal a1 = (Animal)a1.clone();
a2.setName("毛毛");
//发现两个就可以做不同的方法和属性,目前两个就是完全独立的个体

(2) boolean equals(Object obj)
回忆:==是干嘛的?
1.可以在基本类型变量和引用数据类型变量中
基本数据类型变量是值比较数据值是否相等
引用数据类型是比较地址值

int j = 10;
double d= 10.0;
j == d;//true
char c = '10';
j == c;//true
char c1 = 'A';
char c2 = 65;
c1 == c2;//true

那么我们尝试一下手动重写:

public boolean equals(Object obj){
	if(this == object)
	return true;
	if(obj == null)
	return false;
	if(getClass() != obj.getClass())
	return false;
	
	Person other = (Person) obj;
	if(this instanceof obj){
	return this.age == other.age && this.name.equals(obj.name);
	}

}

在这里插入图片描述
上面就会返回true
重写equals的原则
在这里插入图片描述

2.equlas只能适用于引用数据类型,里面参数是对象
注意这里equals一般会重写要不然没意义
打个比方:
假设创建了一个person类,没有重写equals方法
obj的equals源码:
在这里插入图片描述

Person p1 = new Person("ppp",21);
Person p2 = new Person("ppp",21);
p1 == p2;//false
//String 是重写过的
String s1= new String("hello");
String s2= new String("hello");
s1 == s2;//false
s1.equals(s2);//true

(3)finalize()
1.当垃圾收集确定没有对对象的引用时,由对象上的垃圾收集器调用
2.子类可以重写
重写按照api格式重写:

protected void finalize() throws Throwable{
}

3.该方法是finalize最多只调用一次java虚拟机在任何给定的对象
那么什么意思呢?
1.通常不要主动调
2.这方法就是配合垃圾回收器用的
比如:

//create a object
Person p = new Person("peter",12);
//此时实体就是一个垃圾对象没有指向,等待回收
p = null;
//手动回收强制释放空间
System.gc();

在内存中就是实列对象在栈中没有指向的堆内存的时候,就会由垃圾回收器回收之前就会先调用这个方法

思考:final,finally,finalize()区别

(4)toString()
object类定义下的这个方法:
返回的是:
getClass().getName() + ‘@’ + Integer.toHexString(hashCode())
前面调用的全类名
后面是表示内存地址,十六进制表示
直接输出的话
在这里插入图片描述
谁便一个对象也是调用的是obj.toString(),不包括包装类的对象
这里是可以重写的

包装类(wrapper)

有了类的特点,也有了对象的调用方法的能力
在这里插入图片描述
看源码:
在这里插入图片描述
可以看出来实际上就是把它包了一下

还可以看出来它的父类是number,number继承于object
在这里插入图片描述
同时它也实现了序列化接口:
所有包装类都实现了 java.io.Serializable 接口,所以包装类都支持序列化和反序列化

public abstract class Number implements java.io.Serializable {
      ......
  }

类型转化的一个参考图
在这里插入图片描述
我们举几个列子:
实现包装类和基本数据类型的转化

int n1 = Integer.parseInt("100");
  System.out.println(n1);

  int n2 = new Integer(100).intValue();
  System.out.println(n2);

  boolean b1 = Boolean.valueOf("true");
  System.out.println(b1);

  boolean b2 = Boolean.valueOf("tRue");
  System.out.println(b2);

下面程序的输出结果


Integer n1 = 128;
Integer n2 = 128;
System.out.println(n1 == n2);//true

Integer n3 = 129;
Integer n4 = 129;
System.out.println(n3 == n4);//false

高频区间进行了数据缓存

在实践中,大部分数据操作都是集中在较小的数值范围,因此从 Java 5 开始新增了高频区间数据缓存,例如调用 Integer.valueOf 静态方法时,会利用缓存机制,如果缓存中已经存在,则直接返回缓存的对象,而不会重新创建。

各个包装类的缓存范围:

Byte:全部缓存,缓存范围 -128~127
Short:缓存范围 -128~127
Integer:缓存范围 -128~127
Long:缓存范围 -128~127
Float/Double:未缓存
Character:缓存范围 0~127
Boolean:缓存了 true/false 实例,Boolean.TRUE/Boolean.FALSE
注: Integer 是唯一可以通 JVM 参数 -XX:AutoBoxCacheMax=N 来设置缓存上限的。

具体的大家可以看源码:

//标记为native还无法更改
public static final int   MIN_VALUE = 0x80000000;//最小值
public static final int   MAX_VALUE = 0x7fffffff;//最大值

//缓存内容
private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

Double 代码输出结果


Double d1 = 127d;
Double d2= 127d;
System.out.println(d1 == d2);//false

int num = 127;
Double d2= 127d;
System.out.println(num == d2);//true

下面程序的输出结果


Integer n1 = 128;
Integer n2 = new Integer(128);
System.out.println(n1 == n2);//false
System.out.println(n1 .equals(n2));//true

//类型提升
Object o1 = true?new Integer(1):new Double(2.0);//01 == 1.0

Object o2;
if(true)
o2 = new Integer(1);
else
o2 = new Double(2.0);//o2值是1

Integer i = new Integer(1);
Integer j = new Integer(1);
i == j;//false

Integer n1 = 1;
Integer n2 = 1;
n1 == n2;//true

Integer n1 = 128;
Integer n2 = 128;
n1 == n2;//false

包装类有哪些功能


在这里插入图片描述
自动拆箱和自动装箱:

int num = 10;
Integer num2 = 10;
int num3 = num2;

基本数据类型,包装类转String

int num1 = 10;
//方式1
String s = num1 +"";
//方式2
String s2 = String.valueOf(num1);

String,转基本数据类型包装类:
parsexxx(String s)

泛型可以为基本数据类型吗?

泛型不能使用基本数据类型,jvm在编译的时候会进行类型擦除

下面程序的输出结果

System.out.println(1.0-0.5);//不等于0.5

发布了38 篇原创文章 · 获赞 1 · 访问量 2264

猜你喜欢

转载自blog.csdn.net/CRD8843/article/details/103830059
今日推荐