zoukankan      html  css  js  c++  java
  • JAVA核心技术I---JAVA基础知识(常量设计和常量池)

    一:常量---一种不会修改的变量

    –Java没有constant关键字
    –不能修改,final
    –不会修改/只读/只要一份,static
    –方便访问publicJava中的常量
    –public static final
    –建议变量名字全大写,以连字符相连,如UPPER_BOU

    (一)static和final修饰的常量

    public class Constants {
        //使用static和final做到唯一且不可变
        //若是不使用static,则每次产生一个对象,就会产生一个变量不可以修改,但是值却相同,无意义且占据大量空间
        public final static double PI = 3.14;
        public static final String DEFAULT_COUNTRY = "China";    //static 和 final两个的顺序可以变化
        
        public static void main(String[] args) {
            System.out.println(Constants.PI);
            System.out.println(Constants.DEFAULT_COUNTRY);
        }
    }
            PI=3.2;    //The final field Constants.PI cannot be assigned  出错,编译无法通过

    (二)接口内定义的变量默认是常量:不希望别人修改

    public interface ConstantInterface {
        double PI=3.14;  //默认是public static final double PI
        public double getPI();
        public void setPI(double pi);
    }
    public class ConstantTest implements ConstantInterface{
        public double getPI() {
            return PI;
        }
        
        public void setPI(double pi) {
            this.PI=pi;    //The final field ConstantInterface.PI cannot be assigned 出错,编译无法通过
        }
    }

    二:常量池(节约内存,共享访问)

    (一)常量池和包装类

    Java为很多基本类型的包装类/字符串都建立常量池
    常量池:相同的值只存储一份,节省内存,共享访问
    包装类:将8个基本类型,都对应产生一个对应的包装类。(因为java基本上操作的都是对象)

    (二)8个包装类以及对应的常量池(6个):

    基本类型的包装类
    –Boolean,Byte,Short,Integer,Long,Character,Float,Double
    –Boolean: true, false
    –Byte, Character : u0000--u007f (0—127)    128个
    –Short, Int, Long:-128~127    256个
    –Float,Double:没有缓存(常量池)
    java为前面的六个建立的常量池,因为小数东西太多,没办法用常量池
        public static void main(String[] args) {
            System.out.println(Constants.PI);
            System.out.println(Constants.DEFAULT_COUNTRY);
            //PI=3.2;    //The final field Constants.PI cannot be assigned
            Integer n1 = 127;
            Integer n2 = 127;         //在常量池中,所以指向同一块内存
            System.out.println(n1==n2);   //true
    //对象双等号是比较指针是否指向同一个东西
            
            Integer n3 = 128;
            Integer n4 = 128;        //因为包装类Integer只包含-128~127,并没有保存128,所以不在常量池中,不是同一块内存
            System.out.println(n3==n4);  //false
            
            Integer n5 = new Integer(127);//n1在栈上,n5在堆上,自然不在同一块内存区域,自然不一致
            System.out.println(n1==n5);  //false
        }
    public class CacheTest {
        public static void main(String[] args) {
            Boolean b1 = true;  //true,false
            Boolean b2 = true;
            System.out.println("Boolean Test: " + String.valueOf(b1 == b2));
            
            Byte b3 = 127;     //u0000-u007f
            Byte b4 = 127;
            System.out.println("Byte Test: " + String.valueOf(b3 == b4));
            
            Character c1 = 127;  //u0000-u007f
            Character c2 = 127;
            System.out.println("Character Test: " + String.valueOf(c1 == c2));
            
            Short s1 = -128;  //-128~127
            Short s2 = -128;
            System.out.println("Short Test: " + String.valueOf(s1 == s2));
            
            Integer i1 = -128;  //-128~127
            Integer i2 = -128;
            System.out.println("Integer Test: " + String.valueOf(i1 == i2));
            
            Long l1 = -128L;  //-128~127
            Long l2 = -128L;
            System.out.println("Long Test: " + String.valueOf(l1 == l2));
            
            Float f1 = 0.5f;
            Float f2 = 0.5f;
            System.out.println("Float Test: " + String.valueOf(f1 == f2));  //不在常量池中,不是同一块区域,对象不一致false
            
            Double d1 = 0.5;
            Double d2 = 0.5;
            System.out.println("Double Test: " + String.valueOf(d1 == d2));  //不在常量池中,不是同一块区域,对象不一致false
        }
    }

    (三)字符串常量池

    Java为常量字符串都建立常量池缓存
    public class StringConstantTest {
        public static void main(String[] args) {
            String s1 = "abc";
            String s2 = "abc";
            String s3 = "ab" + "c"; //都是常量,编译器将优化,下同
            String s4 = "a" + "b" + "c";
            System.out.println(s1 == s2); //true
            System.out.println(s1 == s3); //true
            System.out.println(s1 == s4); //true
        }
    }
    对于s1 s2 s3都是由常量拼接,编译器将对其进行优化。存放在同一块常量池中

    (四)包装类的两种创建方式:决定是否被常量化

    基本类型的包装类和字符串有两种创建方式
    –常量式(字面量)赋值创建,放在栈内存 (将被常量化)
    • Integer a = 10;
    • String b = “abc”;
    –new对象进行创建,放在堆内存 (不会常量化)
    • Integer c = new Integer(10);
    • String d = new String(“abc”);
    这两种创建方式导致创建的对象存放的位置不同
    栈读取速度快,但是容量小
    堆读取速度慢,但是容量大

    (五)包装类和基本类型 

    1.包装类的名字大写开头,类型名全长
    2.数据---->对象   经过自动装箱
            int i1 = 10;
            Integer i2 = 10;                // 自动装箱

    3.基本类型和包装类型比较时,包装类会自动拆箱。转换为基本数据类型比较
            int i1 = 10;
            Integer i3 = new Integer(10);
            System.out.println(i1 == i3);  //true
            // 自动拆箱  基本类型和包装类进行比较,包装类自动拆箱
    4.两个包装对象比较时,比较其地址
            Integer i2 = 10;                // 自动装箱
            Integer i3 = new Integer(10);
            
            System.out.println(i2 == i3); //false
            // 两个对象比较,比较其地址。 
            // i2是常量,放在栈内存常量池中,i3是new出对象,放在堆内存中
    5.两个包装对象运算时,会先拆箱为基本类型进行运算,返回基本类型
            int i1 = 10;
            Integer i2 = 10;                // 自动装箱
            Integer i3 = new Integer(10);
            
            Integer i4 = new Integer(5);
            Integer i5 = new Integer(5);
            System.out.println(i1 == (i4+i5));   //true
            System.out.println(i2 == (i4+i5));   //true
            System.out.println(i3 == (i4+i5));   //true
            // i4+i5 操作将会使得i4,i5自动拆箱为基本类型并运算得到10. 
            // 基础类型10和对象比较, 将会使对象自动拆箱,做基本类型比较
         i4+i5返回的是10-->是基本数据类型int,不是Integer包装类
    6.装箱的包装对象要参照常量池
            int i1 = 10;
            Integer i2 = 10;                // 自动装箱
            
            Integer i6 = i4 + i5;  // +操作使得i4,i5自动拆箱,得到10,再装箱,放入栈中,可以常量化,因此i6 == i2.
            System.out.println(i1 == i6);  //true
            System.out.println(i2 == i6);  //true
            System.out.println(i3 == i6);  //false
         i4 + i5 ---> 10 存放在栈区,在常量池中,同i2一样是10,存放在常量池中,所以两者相等

    (六)不同类型基本类型和包装类比较

    1.基本类型比较

            short a=1;
            int b=1;
            System.out.println(a==b);
      
            float e = 1;
            System.out.println(e);
            
            double f=1;
            System.out.println(f);
            
            System.out.println(b==e);
            System.out.println(b==f);
            System.out.println(e==f);
    true
    1.0
    1.0
    true
    true
    true

            short a=1;
            char g=1;
            byte h=1;
            System.out.println(g);
            System.out.println(h);
            System.out.println(g==h);    //一个是char类型,一个是byte类型,两个比较都会转换为int类型
            System.out.println(h==a);
    
    1
    true
    true
    1.如果两个操作数中有一个是double类型,另一个操作数就会转换为double类型
    2.否则(没有一个是double类型),如果两个操作数中有一个是float类型,另一个操作数就会转换为float类型
    3.否则(没有一个是double类型和float类型),如果两个操作数中有一个是long类型,另一个操作数就会转换为long类型
    4.否则两个操作数都会被转换为int类型

    2.不同包装类比较

    不允许不同包装类之间比较,编译无法通过

    (七)字符串常量池补充

    1.栈和堆

            String s0 = "abcdef";  //栈,常量池
            String s1 = "abc";    //栈,常量池
            String s2 = "abc";    //栈,常量池
            String s3 = new String("abc");  //堆,单独开辟一块内存
            String s4 = new String("abc");  //堆,单独开辟一块内存
            System.out.println(s1 == s2); //true 常量池
            System.out.println(s1 == s3); //false 一个栈内存,一个堆内存
            System.out.println(s3 == s4); //false 两个都是堆内存

    2.字符串拼接涉及变量,则编译器不会优化

            String s5 = s1 + "def";    //涉及到变量,故编译器不优化
            String s6 = "abc" + "def"; //都是常量 编译器会自动优化成abcdef
            String s7 = "abc" + new String ("def");//涉及到new对象,编译器不优化
            System.out.println(s5 == s6); //false
            System.out.println(s5 == s7); //false
            System.out.println(s6 == s7); //false
            System.out.println(s0 == s6); //true 

    3.字符串拼接涉及new对象,则编译器不会优化

            String s8 = s3 + "def";//涉及到new对象,编译器不优化
            String s9 = s4 + "def";//涉及到new对象,编译器不优化
            String s10 = s3 + new String("def");//涉及到new对象,编译器不优化
            System.out.println(s8 == s9); //false
            System.out.println(s8 == s10); //false
            System.out.println(s9 == s10); //false
  • 相关阅读:
    JAVA 实现json diff
    Apache httpclient拦截器对请求进行签名
    okHttp3教程:5种基本请求示例,拦截器实现自动重试和日志打印
    代码执行testng的几种方式
    封装log4j支持记录到testng
    修改ZuulHandlerMapping私有变量pathMatcher,重写match方法,使url匹配兼容正则表达式。
    修改testng源码,添加beforeMethod和afterMethod中的日志到test中(可以不改源码,废弃)
    Linux Python import jenkins 报错 oserror: /usr/lib/python2.7/site-packages/lookup3.so
    mongodb相关查询
    monkey命令参数介绍
  • 原文地址:https://www.cnblogs.com/ssyfj/p/10196159.html
Copyright © 2011-2022 走看看