1-6 基本类型,操作符,控制,初始化及访问权限

2019-05-08  本文已影响0人  Teemo_fca4
基本类型的取值范围
    public  void t1(){
        //使用10进制 8进制 16进制来赋值数据
        int  int10 = 12; //10进制
        int  int8 = 012; //8进制
        int int16 = 0xff;//16进制
        //数据上溢和下溢
        Integer a = Integer.MAX_VALUE+1;
        Integer b = Integer.MIN_VALUE-1;
        //类型转换优先关系顺序: 小类型数据与大类型数据运算结果是大类型数据
        // byte,short,char >int > long > float > double
    }
基本类型与包装类型

基本类型与包装类型的取舍:我推荐尽量使用包装类型,比如int类型默认初始化值是0,但是有时候我们对于某个字段的要求是无就是无,0代表不了无,因此使用null来表示更适合语义,又比如我们使用int来接受数据库某个字段的值时 假设这个字段对应的记录在数据库中为null,但是我们却以int去接收 ,以mybatis为例 会返回attempted to return null from a method with a primitive return type (int).错误,当数据库返回null,但是我们以int ,boolean ,long等基本类型去接收时就会出现错误,因为基本类型无法赋值为null,
但是基本类型也不是一无是处,基本类型有基本类型的特点,由于基本类型直接存储值,并且放置于栈中,因此比包装类型更加高效。

赋值和方法调用中的别名问题

基本类型及其包装类以及String都是通过复制一个值来来传递
引用类型,数组通过复制地址的值来传递。(以下例子结果在方法调用中表现的也一样)

public class Test1 {
    public static void main(String[] args) {
        int a  = 1;
        int b =a ;
        b = 2;
        System.out.println(a);//输出1
        System.out.println(b);//输出2

        Integer c = 1;
        Integer d = c;
        d = 2;
        System.out.println(c);//输出1
        System.out.println(d);//输出2

        String s1  = "1";
        String s2 = s1;
        s2="2";
        System.out.println(s1);//输出1
        System.out.println(s2);//输出2

        Person p1 = new Person();
        Person p2 = p1 ;
        p2.a=200;
        System.out.println(p1.a);//输出200
        System.out.println(p2.a);//输出200
        System.out.println("---------------");
        Integer[] arr1 = {1,2,3};
        Integer[] arr2 = arr1;
        arr2[0] = 11;
        System.out.println(arr1[0]);//输出11
        System.out.println(arr2[0]);//输出11

        int[] arr3 = {1,2,3};
        int[] arr4 = arr3;
        arr4[0] = 11;
        System.out.println(arr3[0]);//输出11
        System.out.println(arr4[0]);//输出11
    }
}
@Data
class  Person{
    Integer a = 100;
}
类初始化顺序
主要注意,1类初始化<clinit>,2 实例初始化<init>,3 方法重写
public class Son extends Father{
    private static int j = method();
    static{
        System.out.print("(6)");
    }
    {
        System.out.print("(8)");
    }
    private int i = test();
    Son(){
        System.out.print("(7)");
    }
    public int test(){
        System.out.print("(9)");
        return 1;
    }
    public static int method(){
        System.out.print("(10)");
        return 1;
    }
    public static void main(String[] args) {
        Son s1 = new Son();
        System.out.println();
        Son s2 = new Son();
    }
}

public class Father{
    private int i = this.test();

    static{
        System.out.print("(1)");
    }
    
    private static int j = method();
    
    Father(){
        System.out.print("(2)");
    }
    
    {
        System.out.print("(3)");
    }
    
    public int test(){
        System.out.print("(4)");
        return 1;
    }
    public static int method(){
        System.out.print("(5)");
        return 1;
    }
}
//输出结果
//(1)(5)(10)(6)(9)(3)(2)(9)(8)(7)
//(9)(3)(2)(9)(8)(7)

// main方法 所在的类进行初始化  先初始化Father类在初始化Son类
//父类的<clinit>方法 JVM定义的方法,全名 class init,clinit方法只执行一次
//先初始化Father类,静态代码块比静态成员先声明,所以先执行静态代码块
//输出 1 
//然后执行静态成员初始化
//输出5
//父类的<clinit>方法
//再初始化Son类,静态成员比静态代码块先申明,所以先执行静态成员初始化
//输出10
//然后 静态代码块
//输出6
//执行子类的<init>方法,JVM中定义的,new几次对象<init>就执行几次
//然后执行构造函数中第一行super();它比成员变量先执行,
//先执行Father的super();由于父类是Object,所以无任何输出
//然后进行Father的初始化,成员变量初始化优先于构造函数(与声明位置无关)
//执行的Father的test()方法,非静态方法前面其实有一个默认的对象this,this在构造器(或<init>)它表示的是正在创建的对象,因为这里是在创建Son对象,所以test()执行的是子类重写的代码
//输出9
//执行父类的非静态代码块
//输出3
//执行父类的构造函数体
//输出2
//执行子类的成员变量初始化 ,执行test()    
//输出9   
//执行子类的非静态代码块   
//输出8   
//执行子类的构造函数体
//输出7
//**因为创建了两个Son对象,因此实例化方法<init>执行两次**
//输出:9 3 2 9 8 7 
上一篇下一篇

猜你喜欢

热点阅读