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

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

作者: Teemo_fca4 | 来源:发表于2019-05-08 19:30 被阅读0次
    基本类型的取值范围
        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
        }
    
    基本类型与包装类型
    • 对于成员变量,为基本类型时 java会为它们赋予默认值,为包装类型或者引用类型时 java也会为它们赋予默认值null。
    • 对于局部变量,我们需要手动为该变量初始化,否则后面引用到该变量时会编译报错。

    基本类型与包装类型的取舍:我推荐尽量使用包装类型,比如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 方法重写
    • main方法所在的类进行初始化,执行<clinit>类初始化方法(如果有父类,那就执行父类<clinit>)
    • <clinit>实例初始化方法,<clinit>由静态代码块和静态成员变量赋值代码组成(静态成员与静态代码块谁先声明那就先执行谁,这两个都是只执行一次)
    • 实例初始化<init>,<init>()方法可能重载有多个,有几个构造器就有几个版本的<init>方法。
      <init>方法由非静态成员变量和非静态代码块,以及构造器组成。
      执行所在类的<init>方法,先执行super()方法,再执行(成员变量的初始化 ,普通代码块:这两个谁先声明就先执行谁)-->构造函数方法体。
    • 方法重写:子类如果重写了父类的方法,通过子类对象调用的一定是子类重写过的代码,非静态方法默认的调用对象是this,this对象在构造器或者说<init>方法中就是正在创建的对象
    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 
    

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/izzuoqtx.html