• 6 java的基本数据类型和引用数据类型和基本数据类型的对象


    基本数据类型

    int(4字节)Integer
    short(2字节)Short
    long(8字节)Long
    float(4字节)Float
    double(8字节)Double
    byte(1字节)Byte
    char(2字节)Character
    boolean(未定)Boolean

    引用类型

    类,接口,数组

    ● 从概念方法来说:

    • 基本数据类型:变量名指向具体的数值 ,引用数据类型:变量名指向存数据对象的内存地址,即变量名指向hash值

    ● 从内存方法

    • 基本数据类型在被创建时,在栈上给其划分一块内存,将数值直接存储在栈上。
    • 引用数据类型在被创建时,首先要在栈上给其引用(句柄)分配一块内存,而对象的具体信息都存储在堆内存上,然后由栈上面的引用指向堆中对象的地址。

    ● 数据类型在 栈和堆中的区别

    • 静态区: 保存自动全局变量和 static 变量(包括 static 全局和局部变量)。静态区的内容在总个程序的生命周期内都存在,由编译器在编译的时候分配。
    • 堆区: 一般由程序员分配释放,由 malloc 系列函数或 new 操作符分配的内存,其生命周期由 free 或 delete 决定。在没有释放之前一直存在,直到程序结束,由OS释放。其特点是使用灵活,空间比较大,但容易出错
    • 栈区: 由编译器自动分配释放,保存局部变量,栈上的内容只在函数的范围内存在,当函数运行结束,这些内容也会自动被销毁,其特点是效率高,但空间大小有限

    基本数据类型的拆箱装箱

    自动根据数值创建对应的 Integer对象,这就是装箱。
    拆箱,就是自动将包装器类型转换为基本数据类型。
    从反编译得到的字节码内容可以看出,在装箱的时候自动调用的是Integer的valueOf(int)方法,创建对应的对象。
    而在拆箱的时候自动调用的是Integer的intValue方法。

    基本数据类型==和equals区别

    1. equals():用是方法,来检测两个对象是否相等,即两个对象的内容和地址是否相等。
    2. == 是运算符,用于比较引用和比较基本数据类型时具有不同的功能
      ● 基础数据类型:比较的是他们的值是否相等,比如两个int类型的变量,比较的是变量的值是否一样。
      ● 引用数据类型:比较的是引用的地址是否相同,比如说新建了两个User对象,比较的是两个User的地址是否一样。
    • == 运行速度比equals()快,因为==只是比较引用。
    • 像String、Integer等类)对equals进行了重写。但是没有对equals进行重写的类就只能从Object类中继承equals方法,其equals方法与==就也是等效的

    对于基本数据类型equals重写

    • String对equels进行了重写,equals比较的是对象的值是否相同,不判断地址是否相同
    • 对于包装器类型,equals方法并不会进行类型转换,基本型封装类型调用equals(),但是参数是基本类型,这时候,先会进行自动装箱,(equal重写了装箱相关的操作)。当 "=="运算符的两个操作数都是 包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)
    public class Tinterger {
        public static void main(String[] args) {
    
            Integer a = 1;
            Integer b = 2;
            Integer c = 3;
            Integer d = 3;
            Integer e = 321;
            Integer f = 321;
            Long g = 3L;
            Long h = 2L;
            Integer k = 2;
            Double M = 2.0;
    
            System.out.println(c==d);  //true判断对象地址相同,因为在-128~127
            System.out.println(e==f);  //false判断对象地址相同,equal和==是一样的
            System.out.println(e.equals(f)); //true 基本类型的对象重写了equal方法
            System.out.println(c==(a+b)); //true  进行运算自动拆箱比较值
            System.out.println(d.equals(c)); // //true equal比较值是否相同
            System.out.println(c.equals(a+b)); // true  equal比较值是否相同
            System.out.println(g==(a+b));// true  equal比较值是否相同
            System.out.println(g.equals(a+b));// false  equal比较值是否相同
            System.out.println(g.equals(a+h));// true  equal比较值是否相同
            System.out.println(k.equals(M));// true equal比较值是否相同
            System.out.println(1==1.0);// true 比较值是否相同
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    基本数据类型的类封装 ——源码分析

    Integer

    从这2段代码可以看出,在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。
    Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。

    public static Integer valueOf(int i) {
            if(i >= -128 && i <= IntegerCache.high)
                return IntegerCache.cache[i + 128];
            else
                return new Integer(i);
        }
    复制代码
     private static class IntegerCache {
            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++);
            }
    
            private IntegerCache() {}
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    double

    Double类的valueOf方法会采用与Integer类的valueOf方法不同的实现。很简单:在某个范围内的整型数值的个数是有限的,而浮点数却不是。
    double类型的对象创建不使用缓存,每次都新建一个对象
    Double、Float的valueOf方法的实现是类似的。

    Boolean

    Boolean对象内置了两个静态属性对象True和False,每次创建的对象在获得值的都是这两个静态对象的一个,因此不同对象的true和false也都是这一个

    public static Boolean valueOf(boolean b) {
            return (b ? TRUE : FALSE);
    }
    public static final Boolean TRUE = new Boolean(true);
    /** 
         * The Boolean object corresponding to the primitive 
         * value false. 
         */
    public static final Boolean FALSE = new Boolean(false);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    特殊的数据类型

    String

    string是一个类,但是可以和基本数据类型一样做符合赋值。

    BigDecimal

    用来做金钱计算的类,不出现精度损失。金额计算必须用BigDecimalBigDecimal在进行入库时, 数据库选择decimal类型, 长度可以自定义, 如18; 小数点我们项目中用的是2, 保留2位小数. 此外还要注意的就是默认值, 一定写成0.00, 不要用默认的NULL, 否则在进行加减排序等操作时, 会带来转换的麻烦!
    优先使用String构造方法,当double必须用作BigDecimal的源时,请使用Double.toString(double)转成String,然后使用String构造方法,或使用BigDecimal的静态方法valueOf,如下

    功能介绍
    BigDecimal(int) 创建一个具有参数所指定整数值的对象。
    BigDecimal(double) 创建一个具有参数所指定双精度值的对象。
    BigDecimal(long) 创建一个具有参数所指定长整数值的对象。
    BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。
    ===========================================================
    add(BigDecimal) BigDecimal对象中的值相加,然后返回这个对象。
    subtract(BigDecimal) BigDecimal对象中的值相减,然后返回这个对象。
    multiply(BigDecimal) BigDecimal对象中的值相乘,然后返回这个对象。
    divide(BigDecimal) BigDecimal对象中的值相除,然后返回这个对象。
    toString() 将BigDecimal对象的数值转换成字符串。
    doubleValue() 将BigDecimal对象中的值以双精度数返回。
    floatValue() 将BigDecimal对象中的值以单精度数返回。
    longValue() 将BigDecimal对象中的值以长整数返回。
    intValue() 将BigDecimal对象中的值以整数返回。

    public class TBigDecimal {
    
        public static void main(String[] args) {
    
            System.out.println(0.05 + 0.01);
    
            BigDecimal a = new BigDecimal(1.01);
            BigDecimal b = new BigDecimal(1.02);
            BigDecimal c = new BigDecimal("1.01");
            BigDecimal d = new BigDecimal("1.02");
            System.out.println(a.add(b));
            System.out.println(c.add(d));
        }
    
        public static BigDecimal add(double v1, double v2) {// v1 + v2
            BigDecimal b1 = new BigDecimal(Double.toString(v1));
            BigDecimal b2 = new BigDecimal(Double.toString(v2));
            return b1.add(b2);
        }
    
        public static BigDecimal sub(double v1, double v2) {
            BigDecimal b1 = new BigDecimal(Double.toString(v1));
            BigDecimal b2 = new BigDecimal(Double.toString(v2));
            return b1.subtract(b2);
        }
    
        public static BigDecimal mul(double v1, double v2) {
            BigDecimal b1 = new BigDecimal(Double.toString(v1));
            BigDecimal b2 = new BigDecimal(Double.toString(v2));
            return b1.multiply(b2);
        }
    
        public static BigDecimal div(double v1, double v2) {
            BigDecimal b1 = new BigDecimal(Double.toString(v1));
            BigDecimal b2 = new BigDecimal(Double.toString(v2));
            // 2 = 保留小数点后两位   ROUND_HALF_UP = 四舍五入
            return b1.divide(b2, 2, BigDecimal.ROUND_HALF_UP);// 应对除不尽的情况
        }
    
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    静态代码块

    public class P{
        static{
            System.out.println("hell");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    接口和抽象类

    继承父类使用extend

    • 抽象类也是类
    • 满足类的基本继承规则
    • 但是只能通过继承的子类来实例化

    继承接口使用implent

    • 接口可以被继承多个
    • 接口的方法只能抽象,通过字类实现
    • 子类必须实现所有接口方法
    • 接口之间也可以相互继承

    接口的用处

    函数式接口

    只定义一个函数的接口,这个函数可以用来解析表示lambda表达,到时候调用接口的函数就相当只需lambda式里的函数
    另外java内置了一些函数式接口
    在这里插入图片描述
    在这里插入图片描述

    interface Tti{
        void printl();
    }
    public class TestL {
    
        public static void main(String[] args) {
            Tti t = ()-> {System.out.println("hello");};
            t.printl();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    空接口

    不定义任何方法,仅仅用来被继承作为标识

    内部类

    成员内部类

    当某个类除了他的外部类,不会被其他类使用时,使用成员内部类。这种情况下,内部类依附于外部类而存在,原因可能有: 1. 不可能有其他类使用该内部类。 2. 该内部类不能被其他类使用,可能会导致错误。这是内部类使用比较多的一个场景。

    1. 外部类可以直接访问内部类的成员和方法,但是必须先创建一个内部类的对象,再通过该对象使用其成员和方法。
    2. 内部类可以访问外部类的成员和方法,但是要注意,当内部类拥有和外部类相同的成员或方法时,会发生隐藏现象,默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式访问:外部类.this.成员变量/方法
    3. 内部类只是一个编译时的概念,一旦编译成功,就会成为完全不同的两个类。对于一个名为Outer的外部类和其内部定义的名为Inner的内部类,编译完后会生成Outer.class和Outer$Inner.class两个类
    4. 成员内部类与普通的成员没什么区别,可以与普通成员一样进行修饰和限制
       public class Outer {
        private int num = 1;
        private int num1 = 10;
    
        public class Inner {
            private int num = 2;
            public void func () {
                System.out.println(Outer.this.num);
                System.out.println(num1);
            }
        }
    
        public static void main(String[] args) {
            Outer outer = new Outer();
            Inner inner = outer.new Inner();
            inner.func();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    静态内部类

    静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,它不持有指向外部类对象的引用this,并且它不能使用外部类的非static成员或方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体对象。它唯一的作用就是随着类的加载(而不是随着对象的产生)而产生。

        public class Outer {
    
        static class Inner {
            public Inner () {
    
            }
        }
    
        public static void main(String[] args) {
            Outer.Inner innner = new Outer.Inner();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    局部内部类

    局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。局部内部类就像方法里面的局部变量一样,是不能有public、protected、private及static修饰符的。

      public class Outer {
      private int num = 1;
      private int num1 = 10;
    
      public void func () {
          class Inner {
              private int num = 2;
          }
          Inner inner = new Inner();
          System.out.println(inner.num);
      }
    
    
      public static void main(String[] args) {
          Outer outer = new Outer();
          outer.func();
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    匿名内部类

    匿名内部类应该是平时我们编写代码时用的最多的,在编写事件监听的代码时匿名内部类不但方便,而且使代码更加容易维护。匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名为Outer$1.class。一般来说,匿名内部类用于集成其他类或者实现接口,并不需要增加额外的方法,只是对集成方法的实现或是重写。

    public class Outer {
    
       public void func () {
           System.out.println("1");
       }
    
    
       public static void main(String[] args) {
           Outer inner = new Outer() {
               public void func () {
                   System.out.println("2");
               }
           };
           inner.func();
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    国产管理软件勒索病毒大爆发
    ui设计师简历自我评价的范文
    MySQL创建定时任务定时执行sql
    Dubbo负载均衡
    十一、【VUE-CLI】全局事件总线(待办事项案例 · 第四版)
    聚焦离子束FIB测试的计量技术规范盘点
    Springboot丽水土特产销售网站e80z4计算机毕业设计-课程设计-期末作业-毕设程序代做
    Spark - 介绍及使用 Scala、Java、Python 三种语言演示
    团队协作中如何处理ConflictingBeanDefinitionException异常
    把备考高项当成项目:我的信息系统项目管理师项目实施方案
  • 原文地址:https://blog.csdn.net/qq_37771209/article/details/126406096