精华内容
下载资源
问答
  • 常量的分类:静态常量、成员常量局部常量。 public class demo1 { public static final double PI = 3.14;// 静态常量 final int I = 20; // 声明成员常量 public static void main(String[] args) { final double...

    Java变量与常量

    常量

    常量是指在程序执行过程中始终保持不变的量。

    定义语法

    final 常量数据类型 常量名=常量初始值;

    常量的分类:静态常量、成员常量和局部常量。

    public class demo1 {
    public static final double PI = 3.14;// 静态常量

    final int I = 20; // 声明成员常量

    public static void main(String[] args) {
    final double J = 4.5;// 声明局部常量

    }

    在定义常量时,需要注意如下内容:

    在定义常量时就需要对该常量进行初始化。初始化过后其值不能修改。

    final 关键字不仅可以用来修饰基本数据类型的常量,还可以用来修饰对象的引用或者方法。

    为了与变量区别,常量取名一般都用大写字符。

    常量值的分类:整数常量值、实型常量值、布尔型常量值、字符型和字符串常量值

    final int demo1=十进制数、八进制数、十六进制数;//这就是整数常量值

    final int demo1=十进制数形式:由数字和小数点组成,且必须有小数点,如 3.14、-3.14。

    科学记数法形式:如 3.14e5 或 53E3,其中 e 或 E 之前必须有数字,且 e 或 E 之后的数字必须为整数。

    //以上就是实型常量值

    final int demo1=true或false//这就是布尔型常量值

    final int demo1='a’或"a"//这就是字符型和字符串常量值

    变量

    注意事项

    所有的变量必须先声明、后使用。

    赋值的数据类型必须跟声明的数据类型相同。

    基本语法

    int i;//先声明、后赋值

    i=10;

    或者

    int i=10;//声明时直接赋值

    int i=10,j=15,k=60;//可以同时声明多个数据类型相同的变量

    初始化变量有两种方式:一种是声明时直接赋值,一种是先声明、后赋值。

    根据作用域的不同,一般将变量分为不同的类型:成员变量和局部变量。

    成员变量

    成员变量分为:全局变量也称实例变量和静态变量也称类变量。

    public class demo1 {
    int i=10; // 全局变量、实例变量

    static final String web= “CSDN博客网”; //静态变量、类变量

    }

    局部变量

    局部变量是指在方法或者方法代码块中定义的变量,其作用域是其所在的代码块。

    可以分为以下三种

    方法参数变量:

    public class demo1 {
    public static void main(String[] args) {
    int i = 10;

    if (10 > 2) {
    int j = 3; // 声明一个 int 类型的局部变量

    System.out.println(“j=” + j);

    }

    System.out.println(“i=” + i);

    }

    }

    方法局部变量:

    public class demo1 {
    public static void test(int i) {
    System.out.println(“i=” + i);

    }

    public static void main(String[] args) {
    test(8);

    }

    }

    代码块局部变量:常用于异常处理try catch中,成为异常处理参数变量。

    try {
    } catch (Exception e) { // 异常处理块,参数为 Exception 类型

    }

    展开全文
  • 对于字符串比较,我习惯用法是变量.equals(常量) 比如:a.equals("a") 今天看视频才知道变量在前面与后面有很大影响,正确写法是常量放前面(可以避免变量为null引起异常),变量放后面,则上面需要改为("a...

    对于字符串比较,我的习惯用法是变量.equals(常量)

    比如:a.equals("a")

    今天看视频才知道变量在前面与后面有很大影响,正确的写法是常量放前面(可以避免变量为null引起的异常),变量放后面,则上面需要改为("a").equals(a)。

    对于JDK API上字符串的equals的官方解释是

    比如

    public class equalsTest {
    
        @SuppressWarnings("rawtypes")
        public static void main(String args[]) {
            List list = new ArrayList();
            String str = null;
            System.out.println("0".equals(str));
            System.out.println(str.equals("0"));
            System.out.println("0".equals(list.get(2)));
            System.out.println(list.get(2).equals("0"));
        }
    }

    上面依次输出

    false
    java.lang.NullPointerException
    java.lang.IndexOutOfBoundsException: Index: 2, Size: 0
    java.lang.IndexOutOfBoundsException: Index: 2, Size: 0

    对于判断是否为空  str!=null,这个应该变量放前面后面一般没影响,养成好的习惯的话变量也放在后面。一般对一个字符串进行判断首先进行非空判断,然后进行字符串内容判断,一个正确的例子

    null !=string && !("").equals(string.trim()) && !("null").equals(string);
    展开全文
  • java的变量和常量以及常量池

    千次阅读 2017-10-24 17:39:10
    首先变量和常量名都是用户自行定义的标志符,遵循先定义后使用的原则,常量和变量的区别是常量之后会不会改变 变量 占据着内存的某一存储区域,该区域有自己的名称和数据类型,该区域的数据可以在同一...
    首先变量名和常量名都是用户自行定义的标志符,遵循先定义后使用的原则,常量和变量的区别是常量之后会不会改变

    变量

    占据着内存的某一存储区域,该区域有自己的名称和数据类型,该区域的数据可以在同一类型范围内不断的变化,那么为什么定义变量,可以用来存放同一类型的变量可以重复使用,每一个变量都有他自己的作用范围,定义开始到定义它的代码块结束,同一代码块范围内不允许有多个相同名字的局部变量
    局部变量和成员变量:
    局部变量:声明在方法括号里的变量,只能在方法体中使用和访问,其它方法体访问不到,是类中方法体内定义的变量所以叫局部变量
    成员变量:声明在类括号内,方法括号外的变量,又称为field或全局变量,成员变量就是全局变量,其实java内没有全剧变量的概念因为java面向对象的特性所有变量都是类的成员之一所以指的是这个类的变量

    常量

    在程序运行时有两个作用,代表常数便于程序的修改,增强程序的可读性,常量也可以先声明在赋值,但只能赋值一次,主要利用final关键字来进行常量定义
    第一种是一个值,这个值本身,就叫做常量
    第二种是不可变的变量也就是我们都知道的关键字final修饰的变量



    过渡
    在进行常量池的内容之前先进行一个简单的例子String s = new String("hello");这个语句创建了几个字符串?
    答案是两个。这两个字符串创建的时间不同,一个是编译期另一个是运行期。为什么会出现这种情况?



    常量池
    常量池在java用于保存在编译期已经确定的,已编译的class文件中的一份数据,包括了关于类,方法、接口等中的常量,也包括字符串常量,执行产生的常量也放入常量池,故认为常量池是JVM的一块特殊的内存空间,所以首先表达一下JVM的内存分布,有程序计数器,本地方法栈,虚拟栈,方法区,虚拟机堆。
    程序计数器:是JVM执行程序的流水线,存放一些跳转指令
    本地方法栈:是JVM调用操作系统方法所使用的栈
    虚拟机栈:是JVM执行java代码所使用的栈
    方法区:存放了一些常量、静态变量、类信息,可以理解为class文件在内存中的存放位置,这个方法区和常量池密不可分,常量池可以理解为class文件的资源仓库
    虚拟机堆:是JVM执行java代码所使用的堆

    常量池的好处
    为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享,节省内存空间,常量池中所有相同的字符串常量被合并只占用一个空间,节省运算时间比较两个引用变量只用==判断引用是否相等就可以判断实际值是否相等,在需要一个对象时就可以从池中取出来一个在需要重复创建相等变量时节省了大量时间。所以八个基本类都实现了常量池(浮点类型的包装类没有实现,整型的包装类也只有在对应值)。


    java的常量池分为三种形态

    (1)class文件常量池:class文件中的常量池,class文件中不仅仅包含类的版本、字段、方法、接口等信息,还有就是占用class文件绝大部分空间的常量池主要存放字面量和符号引用(包括类和接口的全限定名,字段的名称和描述符,方法的名称和描述符),每个class文件常量池都对应一个运行时常量池。即在编译的时候如果发现其它类方法的调用或者对其它类字段的引用的话,记录进class文件中的只是一个文本形式的符号引用

    (2)运行时常量池:是JVM在完成类的装载后,将存在于class文件中的常量池载入到内存中并保存到方法区(即java在执行某个类的时候必须经过加载、连接(包括验证、准备、解析)、初始化),在类加载到内存中时就会将class常量池的内容存放到运行时常量池,运行时常量也是每个类都有一个,在经过解析的时候就会根据文本信息把符号引用替换成直接引用,解析的过程会查询全局字符串池以保证运行时常量池所引用的字符串与全局字符串池是一样的
    可与用intern的方法进行扩充,我们常说的常量池就是指方法区中的运行时常量池,它是方法区的一部分,用于存放编译期生成的字面量和符号应用这部分内容将在类加载后进入方法区的时候存入到运行时常量池,而且运行时常量池还有更重要的特性“动态性”,java要求编译期的常量池的内容可以放入池中。
    java的八个基本类的包装类大部分都实现了常量池技术,但是String也实现了常量池也就出现了全局字符串常量池

    (3)全局字符串池:这里的内容是在类加载完成后经过验证,准备阶段之后在堆中生成字符串对象实例,然后将该字符串对象的实例引用值存到该全局字符串池中(这里存的是引用值而不是具体的实例对象,具体的实例对象在堆中开辟了一块内存空间),实现该功能的是一个String Table类,它是一个哈希表里面存的是驻留字符串(双引号括起来的)的引用(意思是不是字符串的本体),在每个JVM里只有一份。

    只有更好的关注编译期的行为,才能更好的理解常量池,运行时的常量池的常量,基本来源于各个class文件的常量池,程序运行时,除非手动向常量池中添加常量(例如intern方法)否则JVM不会自动添加常量到常量池,实际上有多种常量池比如整形常量池等等,但是数值类型的常量池不可以手动添加常量,程序启动时常量池中的常量就已经确定了。
    比如一个程序在经过编译之后在该类的class常量池中存放一些符号引用,然后类加载后将class常量池中的符号引用转存到运行时常量池在经过验证准备阶段之后在堆中生成驻留字符串的实例对象,将这个对象的引用存到全局字符串池,在解析阶段要把运行时常量池中的符号引用替换成直接引用,就会直接查询String Table保证里面的引用值和运行时常量池中的引用值一致。

    字符串驻留

    首先要知道可变类和不可变类
    可变类:当获得这个类的实例引用,可以改变类的实例内容
    不可变类:当获得这个类的实例引用,不可以改变这个实例的内容,不可变类的实例一但被创建,其内在成员变量的值就不能被改变,比如String
    为什么使用不可变对象,以Sring为例:不可变对象可以提高Sting Pool的效率(即字符串常量池)和安全性,如果知道一个对象是不可变的,那么就需要拷贝这个对象的内容时,就不需要复制本身而是复制地址,同时不可变的对象对于线程也是安全的不会因为多线程同时进行导致值的改变。

    java会确保一个字符常量只有一个拷贝,双引号里的都是字符串它们在编译期就被确定了,但是用new String()创建的字符串不是常量不能再编译期确定,所以new String()创建的字符串不能放进常量池中,有自己的空间,在使用intern之后可以将其保存到一个全局String表里,如果具有相同值的Unicode字符串在这个表里,那么该方法返回表中已有字符串的地址并且不会将外部的字符串放入常量池,如果不同会将外部字符串放入池中,并返回字符串的句柄(但是不是将自己的地址注册到常量池中,因为S1 == S1.intern()的结果是false,如果是将地址注册到常量池中那么这个使用==来测试是否为同一个字符串的结果应该是true,也就是说之前的字符串还是存在的)。
    String是不可变的所以在进行拼接的时候,会生成很多临时变量,这是建议使用StringBuffer的原因,因为StringBuffer可变。


    常量池的具体结构

    在java语言中一切都是动态的,编译时如果发现对其他类方法的调用或者对其他类字段的引用的语句,记录进class文件中的只能是一个文本形式的符号引用,在连接过程中,虚拟机根据这个文本信息去查找对应的方法或字段,所以与java的所谓常量不同,class文件中的常量内容丰富,这些常量集中在class中的一个区域存放,一个接着一个就是常量池,在java程序中有很多东西是永恒的,不会再运行过程中变化,比如一个类的名字,一个类字段的名字/所属类型,一个类方法的名字/返回类型/参数名与所属的类型,一个常量,还有在程序中的字面值,这些在JVM解释执行的时候非常重要,会用一部分字节分类存储这些代码,这些字节就是常量池但是只有JVM加载class后在方法区为它们开辟了空间
    常量池中的常量表,这些常量表之间又有不同,class文件中一共有11种常量表:
    (1)_Utf8:用UTF-8编码方式来表示程序中所有的重要常量字符串
    (3-6)_Integer、_Float、_Long、_Double:所有基本数据类型的字面值
    (7)_Class:使用符号引用来表示类或接口,知道所有类名都以_Utf8表的形式存储,但是不知道_Utf8表中哪些字符串是类名哪些是方法名,因此必须用一个指向类名字符串的符号引用常量来表明
    (8)_String:指向包含字符串字面值的Utf8表
    (9-11)_Fieldref、_Methodren、_InterfaceMethodref:指向包含该字段或方法的名字和描述符的Utf8表以及指向包含该字段或方法的名字和描述符_NameAndType表
    (12)_NameAndType:指向包含该字段或方法的名字和描述符的Utf8表
    在源代码中的每一个字面值字符串,都会在编译成class文件阶段,形成标志号(8)的常量表,在JVM加载时会为对应的常量池建立一个内存的数据结构,并存放在方法区中,同时JVM会自动为常量表中的字符串常量的字面值在堆中创建新的String对象,然后把_String常量表的入口地址变为这个堆中String对象的直接地址(常量池解析)
    源代码中所有相同字面值的字符串常量只可能建立唯一一个拘留字符串的对象,实际上JVM是通过一个记录了拘留字符串引用的内部数据结构来维持这一特性,在java中可以调用String的intern()方法来使得一个常规字符串对象成为拘留字符串对象
    String s = new String("Hello world");在运行指令之前JVM就会在堆中创建一个拘留字符串,然后用这个拘留字符串的值来初始化堆中new指令创建出来的新的String对象
    String s = "Hello World";此时局部变量存储的是早已创建好的拘留字符串的堆地址
    new String创建的字符串不是常量不能在编译期确定,所以new出的String对象不放入常量池有自己的地址空间,而且由于String对象的不变性机制会使修改字符串时产生大量的对象,因为每次改变字符串时都会生成一个新的字符串,java为了更有效的使用内存常量池在编译器遇见字符串时会检查池内是否已经存在相同的String字符串,找到了就会把新变量的引用指向现有的字符串对象,没找到就创建新的,所以对一个字符串对象的修改会产生新的对象,之前的依然存在并等待垃圾回收。


    class文件结构(可以用winhex打开二进制格式 文件)
    因为在class文件的一些字节构成了常量池,所以进入class文件进行了解
    开头的四个字节是class文件的魔数,用来标示这是一个class文件,紧接着四个字节是java的版本号,接下就是常量池入口,入口处用两个字节标示常量池常量数量,常量池中存放了各种类型的常量都有自己的类型和存储规范
    魔数:唯一作用就是确定了这个文件是否被JVM接受,很多文件存储标准中都使用魔数来进行身份识别
    版本号:第五、六个字节是次版本号,第七个和第八个是主版本号
    常量池入口:由于常量池中的常量的数量不是固定的,所以常量池入口需要放置一项u2类型的数据,代表常量池的容量计数制
    常量池:主要存放两类常量(字面量和符号引用)即语言层面的常量概念和类和接口的权限定名、字段的名称和描述符、方法的名称和描述符

    展开全文
  • Java中静态常量和静态变量的区别

    万次阅读 2019-02-10 01:32:03
    如下:测试java中静态常量和静态变量区别的样例,表明两者加载时的区别。 StaticClass类中定义了静态常量FIANL_VALUE静态变量VALUE,静态代码块的打印语句表示类被加载 public class StaticClass {   ...

    如下:测试java中静态常量和静态变量区别的样例,表明两者加载时的区别。

    StaticClass类中定义了静态常量FIANL_VALUE和静态变量VALUE,静态代码块的打印语句表示类被加载

    public class StaticClass {  
    
        static {  
            System.out.println("StaticClass loading...");  
        }  
          
        public static String VALUE = "static value loading";  
          
        public static final String FIANL_VALUE = "fianl value loading";  
    }  
    

    StaticClassLoadTest类用于测试静态变量的加载:

    public class StaticClassLoadTest {  
          
        public static void main(String[] args) {  
            System.out.println("StaticClassLoadTest...");  
            printStaticVar();  
        }  
          
        private static void printStaticVar() {  
            System.out.println(StaticVar.FIANL_VALUE);  
            System.out.println(StaticVar.VALUE);  
        }  
          
    }  

    输出:

    StaticClassLoadTest...
    fianl value loading 
    StaticClass loading...  
    static value loading 

    输出显示在打印静态常量时,StaticVar类并没有被加载,在输出静态变量的前才打印类加载信息。这表明类的未加载的情况下也能引用其静态常量信息,原因是因为常量值存储在JVM内存中的常量区中,在类不加载时即可访问。

    注:经过编译优化,静态常量 FIANL_VALUE 已经存到NotInit类自身常量池中,不会加载StaticClass  

     Java中的常量池,实际上分为两种形态:静态常量池运行时常量池

         所谓静态常量池,即*.class文件中的常量池,class文件中的常量池不仅仅包含字符串(数字)字面量,还包含类、方法的信息,占用class文件绝大部分空间。这种常量池主要用于存放两大类常量:字面量(Literal)符号引用量(Symbolic References),字面量相当于Java语言层面常量的概念,如文本字符串,声明为final的常量值等,符号引用则属于编译原理方面的概念,包括了如下三种类型的常量:

    • 类和接口的全限定名
    • 字段名称和描述符
    • 方法名称和描述符

         而运行时常量池,则是jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池。

    运行时常量池相对于CLass文件常量池的另外一个重要特征是具备动态性,Java语言并不要求常量一定只有编译期才能产生,也就是并非预置入CLass文件中常量池的内容才能进入方法区运行时常量池,运行期间也可能将新的常量放入池中,这种特性被开发人员利用比较多的就是String类的intern()方法。

    String的intern()方法会查找在常量池中是否存在一份equal相等的字符串,如果有则返回该字符串的引用,如果没有则添加自己的字符串进入常量池。

     

    常量池的好处
    常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享。
    例如字符串常量池,在编译阶段就把所有的字符串文字放到一个常量池中。
    (1)节省内存空间:常量池中所有相同的字符串常量被合并,只占用一个空间。
    (2)节省运行时间:比较字符串时,==比equals()快。对于两个引用变量,只用==判断引用是否相等,也就可以判断实际值是否相等。

    因此public static final String FIANL_VALUE = "fianl value loading"; 字面量 被存储到了常量池中。


    但是不能说所有的静态常用访问都不需要类的加载,这里还要判断这个常量是否属于“编译期常量”,即在编译期即可确定常量值。如果常量值必须在运行时才能确定,如常量值是一个随机值,也会引起类的加载,如下:

    public static final int FINAL_VALUE_INT = new Random(66).nextInt();  

     

    展开全文
  • 在程序中存在大量数据来代表程序状态,其中有些数据在程序运行过程中值会发生改变,有些数据在程序运行过程中值不能发生改变,这些数据在程序中分别被叫做变量和常量。 变量 变量是程序中最基本存储单元,...
  • 这个是一套系列教程,一共14天,每天8篇,每篇需要5...本篇目录一、常量二、变量2.1 变量的概述2.2 变量的声明和初始化2.3 变量的分类2.4 局部变量和成员变量的区别 一、常量 常量:常见的数值类型(也称为数据常...
  • 1、常量的定义:在程序执行的过程中,其值不可以发生改变的量。  常量的分类: 类型 举例 类型 举例 整数常量 12,-21 字符串常量 "HelloWorld" 字符常量 ‘a','0','A' 布尔...
  • https://blog.csdn.net/qq853632587/article/details/78194768 -Java中静态常量和静态变量的区别 静态常量:static final 静态变量:static 这两者都存储在方法区中(个人理解:常量静态变量区) 在某些情况...
  • 注意Python的区别,Python中标识符由字母、下划线数字组成,且数字不能开头,也是严格区分大小写(但是不包含$) 二.关键字 三.变量  1.什么是变量:(Python一致,但是Python在定义变量时不用指定类型...
  • 如下:测试java中静态常量和静态变量区别的样例,表明两者加载时的区别。 StaticClass类中定义了静态常量FIANL_VALUE静态变量VALUE,静态代码块的打印语句表示类被加载: [java]view plaincopy ...
  • 变量和常量是在许多编程语言中经常涉及到的两个概念,变量的值可以改变而常量的值在初始化后就不能改变。常量在定义是需要用final关键字来修饰。@Test public void testVarAndCon(){ final int CONST=100;//定义并...
  • Java的常量和变量

    2019-07-08 20:48:15
    Java中存在这变量和常量,在平时的使用中和这两者都是分不开的,我们来看看Java中的常量和变量有哪些区别和特点吧 常量 常量的定义:常量就是一个固定不变的量(或者值)已知的值。例如 123,45,1.2,false等 常量...
  • 我下图代码第五行和第九行分别定义了一个整型变量和一个整型常量: ...下面我们就用javap将.class文件反编译出来然后深入研究Java里整型变量和整型常量的区别。 使用命令行javap -c constant.ConstantFoldi...
  • 完美解析java常量和变量之间的区别

    千次阅读 2017-08-13 14:19:19
    常量代表程序运行过程中不能改变值。 语法格式 [访问修饰符]final 数据类型 常量名称 = 值;关键字final不可缺,常量名称要求必须大写。其中中括号内容是可选项, 特点 1.有关键字final 2.在...
  • /*  面试题:  byte b1=3,b2=4,b;  b=b1+b2; ... 哪句是编译失败呢?... 因为变量相加,会首先看类型问题,最终把结果赋值也会考虑类型问题。  常量相加,首先做加法,然后看结果是否在赋值...
  • 由static修饰的变量常量和方法被称作静态变量常量和方法。 被声明为static的变量常量和方法被称为静态成员。静态成员属于类所有,区别于个别对象,可以在本类或其他类使用类名"."运算符调用成员变量 语法...
  • 以下是一个测试java中静态常量和静态变量区别的样例,表明两者加载时的区别。 StaticVar类中定义了静态常量FIANL_VAR静态变量VAR,静态代码块的打印语句表示类被加载: public class StaticVar { static...
  • 1.变量相加 ...2、b1b2是两个变量变量存储值是变化,在编译时候无法判断里面具体值,相加有可能会超出byte取值范围。 2.常量相加 通过原因: Java编译器有常量优化机制,在编译时...
  • 第二章 第15节Java语言基础(面试题之变量相加和常量相加的区别)
  • static修饰的变量、常亮方法被称为静态变量常量和方法。 被声明为static的变量常量和方法被称为静态成员。静态成员属于类所有,区别于个别对象,以在本类或其他类类使用类名“.” 运算符调用静态成员。 ...
  • 1.作为GC Roots的对象有以下几种 虚拟机栈(栈帧中的局部变量区,也叫局部变量表)中...静态变量(类变量的区别 成员变量(实例变量)&局部变量区别: 作用域 成员变量:针对整个类有效。 局部变量:只在...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,703
精华内容 681
关键字:

java变量和常量的区别

java 订阅