java-自动装箱/自动拆箱/对象克隆/枚举/参数可变

一.自动装箱和拆箱
a.包装器定义:所有的基本类型都对应一个类,如int基本类型对应Integer类, 这些类就称为包装器;
b.包装器类名字:Integer/Long/Float/Double/Short/Byte/Character/Void/Boolean前六个的类派生与公共的超类Number
c.对象包装器类的特点:
1.对象包装器类是不可改变的,即一旦构造了包装器,就不允许更改包装在其中的值。
2.对象包装器还是final,不可以定义子类
d.自动装箱和自动拆箱
自动装箱: list.add(3); 等价于 list.add(Integer.valueOf(3)); 这种变换就称为自动装箱;
自动拆箱:将一个Integer对象 赋给一个 int值时,将会自动拆箱;
int n = list.get(i); 等价于 int n = list.get(i).intValue();
e.认为基本类型与他们的对象包装器是一样的, 只是他们的相等性不同;包装器类的 == 运算符检测的是对象是否指向同一个存储区域;解决的办法为equals

        Integer a = 1000;
        Integer b = 1000;//对象过大不是一个整数
        System.out.println(a==b);//结果为false
        System.out.println(a.equals(b));//结果为true
        享元设计模式flyweight
        Integer c=12;
        Integer d=12;//对象在范围之内被固定了
        System.out.println(c==d);//结果为true

自动装箱规范要求 boolean、byte、char<=127,介于 -128~127 间的short和int 被包装到固定的对象中;
装箱和拆箱是编译器认可的,不是虚拟机认可的。
使用数值对象包装器 还有一个好处: 可以将某些基本方法放置在 包装器中, 如, 将一个数字字符串转换成数值; 如 int x = Integer.parseInt(s);

实训练习

    num=Integer.parseInt("123");//字符串--->int 
    system.out.println(num+1)
    二进制/十六进制/八进制转换

public class AutoBox {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //基本数据--->转包装类
        Integer a1=new Integer(12);
        a1=Integer.valueOf(24);//int转换成包装类
        a1=Integer.valueOf("24");//string转换成包装类
        System.out.println(a1);
        Integer st2=new Integer("123");
        //包装类--->基本数据类型
        int num=a1.intValue();
        System.out.println(num);
        //字符串--int
        num=Integer.parseInt("123");
        //转换成二进制
        String str=Integer.toBinaryString(16);
        System.out.println(str);
        //转换成十六进制
        String str1=Integer.toHexString(16);
        System.out.println(str1);
        //转换成八进制
        String str3=Integer.toOctalString(16);
        System.out.println(str3);
    }

}

三.对象克隆
当拷贝一个变量时,原始变量与拷贝变量引用同一个对象。
克隆:如果创建一个对象的新的对象1,它的最初状态与对象2相同,但以后将可以各自改变各自的状态,那就需要使用clone方法
默认的克隆是浅拷贝:子对象不可以变
深拷贝:子对象可变

学习连接:http://blog.csdn.net/pacosonswjtu/article/details/49894755
四.枚举
1.用普通类模拟枚举的实现原理
用普通类实现枚举功能,定义一个Weekday的类来模拟枚举功能

私有的构造方法
每个元素分别有一个公有的静态成员变量表示
可以有若干共有方法或抽象方法,例如,要提供NextDay方法必须是抽象的
采用抽象方法定义nextDay就将大量的if-else语句转移成一个个独立的类

无抽象类
public  class Weekday {
    private Weekday(){}//私有的构造方法
    public final static Weekday SUN=new Weekday();
    public final static Weekday MON=new Weekday();
    public Weekday nextDay()
    {
        if(this==SUN)
        {
            return MON;
        }else {
            return SUN;
        }
    }
    public String toString()
    {
        return this==SUN?"SUN":"MON";

    }
}
抽象类的使用
public abstract class Weekday {
    private Weekday(){}
    public final static Weekday MON=new Weekday() {

        @Override
        public Weekday nextDay() {
            // TODO Auto-generated method stub
            return SUN;
        }
    };
    public final static Weekday SUN=new Weekday() {

        @Override
        public Weekday nextDay() {
            // TODO Auto-generated method stub
            return MON;
        }
    };
    public abstract Weekday nextDay();//抽象类
    public String toString()
    {
        return this==SUN?"SUN":"MON";

    }
}
Test类使用
public class Enum_Test {
public static void main(String[] args) {
        Weekday weekday=Weekday.SUN;//常量复制给对象
        System.out.println(weekday.nextDay());
}
}

2.枚举的应用

public class Enum_Test {
public static void main(String[] args) {
        Weekday weekday=Weekday.SUN;//常量复制给对象
//      System.out.println(weekday.nextDay());
        System.out.println(weekday);
        System.out.println(weekday.ordinal());//在枚举中的排行
        System.out.println(weekday.getClass());
        System.out.println(weekday.name());//SUN
        System.out.println(Weekday.valueOf("SUN").toString());//SUN
        System.out.println(Weekday.values().length);//7
}
public enum Weekday{
    SUN,MON,TUE,WED,THI,FRI,SAT;
}
}

3.带有构造方法的枚举

列表必须放在最前面;构造方法必须私有

public class Enum_Test {
public static void main(String[] args) {
        Weekday weekday=Weekday.SUN;//常量复制给对象
//      System.out.println(weekday.nextDay());
        System.out.println(weekday);
        System.out.println(weekday.ordinal());//在枚举中的排行
        System.out.println(weekday.getClass());
        System.out.println(weekday.name());//SUN
        System.out.println(Weekday.valueOf("SUN").toString());//SUN
        System.out.println(Weekday.values().length);//7
}
/*
所有的枚举类型都是 Enum类的子类: 它们继承了这个类的许多方法,包括toString方法, 它可以返回枚举常量名;如, Size.SMALL.toString() 将返回字符串 “SUN”;
toString 的逆方法是静态方法valueOf: 如,Weekday.valueOf("SUN").toString(); 将s 设置为 Weekday.SUN;
每个枚举类型都有一个静态的values方法: 它将返回一个包含全部枚举值的数组;
System.out.println(Weekday.values().length);
ordinal : 该方法返回enum声明中枚举常量的位置, 从0开始计数;
*/
public enum Weekday{
    SUN(1),MON(),TUE,WED,THI,FRI,SAT;
    private Weekday(){System.out.println("first");}
    private Weekday(int day){System.out.println("second");}
}
}

4.实现带有抽象方法的枚举
如果枚举只有一个成员则可以当成一个单列的实现方式。
单列模式也可以用一个枚举类完成。

模拟实现交通灯的枚举类
public enum TrafficLamp{
    RED(30){
        @Override
        public TrafficLamp nextLamp() {
            // TODO Auto-generated method stub
            return GREEN;
        }
    },GREEN(45){
        @Override
        public TrafficLamp nextLamp() {
            // TODO Auto-generated method stub
            return YELLOW;
        }
    },YELLOW(5){
        @Override
        public TrafficLamp nextLamp() {
            // TODO Auto-generated method stub
            return GREEN;
        }
    };
    public abstract TrafficLamp nextLamp();//返回值必须是枚举类型(类)
    private int time;
    TrafficLamp(int time){this.time=time;}//构造函数,传递时间
}

5.注意点

public enum Size {SMALL, MEDIUM, LARGE, EXTRA_LARGE};

在比较两个枚举类型时,不需要使用 equals, 而直接使用 == 就可以了;
所有枚举类型都是Enum类的子类,它们继承了这个类的许多方法,包括toString方法, 它可以返回枚举常量名;如, Size.SMALL.toString() 将返回字符串 “SMALL”;

public enum Size
{
    SMALL("S"), MEDIUM("M"), LARGE("L"), EXTRA_LARGE("XL");
    private Size(String abbreviation) {this.abbreviation == abbreviation};
    public String getAbbreviation() { return abbreviation; }
}

toString 的逆方法是静态方法valueOf: 如,Size s = Enum.valueOf(Size.class, “SMALL”); 将s 设置为 Size.SMALL;
五.参数可变
a.printf 方法是这样定义的:
这里的省略号… : 是java程序的一部分, 它表明这个方法可以接收任意数量的对象(除 fmt参数外);

public class PrintStream
{
    public PrintStream printf(String fmt, Object... args) {return format(fmt, args) ;}
}

b.实际上, printf 方法接收了两个参数, 一个是格式字符串,另一个是 Object[] 数组, 其中存储着所有的参数;换句话说, 对于printf来说, Object… 与 Object[] 完全一样;

public class PrintStream_Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int n;
        n=100;
        System.out.printf("%d %s",new Object[]{new Integer(n),"wights"});
        System.out.println();
        test(new Object[] {new Integer(n),"wights"});
    }
    public static void test(Object ...objects)
    {
        for(Object obj:objects)
            System.out.println(obj.toString());
    }

}

用于自定义可变参数的方法(计算若干个数值的方法):
可以将 一个数组传递给 可变参数方法的最后一个参数:

max(new double[]{1,2,3,4,5,6,7,9})

public static double max(double... values)
{
    double largest = Double.MIN_VALUE;
    for(double v: values) if(v > largest) largest = v;
    return largest;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值