java 变量与常量

Java 变量和常量

 

Generalization

    在程序中存在大量的数据来代表程序的状态,其中有些数据在程序的运行过程中值会发生改变,有些数据在程序运行过程中值不能发生改变,这些数据在程序中分别被叫做变量和常量。


一、变量variable

 1.变量代表程序的状态,所有程序都使用变量临时存储各种数据。

 2.Java语言是一种强类型的语言总是强制类型定义的语言,要求变量的使用要严格符合定义,所有变量都必须先定义后使用。E.gjava.NETC++python一般说来,在创建大型程序时,强类型有助于减少程序错误。,所以变量在使用以前必须首先声明

 3.Java支持变量

I.局部变量

·局部变量的方法,构造函数或块中声明。

·创建局部变量的方法,构造函数或块时进入,一旦退出方法,构造函数或块中的变量将被销毁。

·访问修饰符不能用于局部变量。

·局部变量是可见的,只有内声明的方法,构造函数或块。

·局部变量在堆栈级别内部实现。

·在这里对局部变量没有默认值,因此局部变量应该声明和初始值应在第一次使用前分配。

II.实例变量

·实例变量在类中声明,但在方法的外面,构造函数或任何块。

·当空间分配给某个对象在堆中,插槽为每个实例变量创建值。

·实例变量认为必须由一个以上的方法,构造函数或块,或一个对象的状态的关键部分必须出现在整个类中引用的值。

·实例变量可以在使用前或后级的级别声明。

·访问修饰符可以给出实例变量。

·实例变量对于所有方法,构造函数和块在类中可见。通常,建议,使这些变量私有(接入层)。然而能见度子类可以给这些变量与使用访问修饰符。

·实例变量有默认值。对于数字的默认值是0,为布尔值是false和对象引用为null。值可以在声明或构造函数中分配。

·实例变量可以直接通过调用变量名的类的内部访问。然而在静态方法和不同的类(当实例变量被赋予访问)应使用完全限定名调用 ObjectReference.VariableName.

III.类/静态变量

·类变量也称为静态变量在类的static关键字声明的,但在方法外面,构造函数或块。

·每个类变量只有一个副本,不管有多少对象从它被创建。

·静态变量很少使用不是被声明为常量等。常量是被声明为公共/私营,最终和静态变量。常量变量从来没有从他们的初始值改变。

·静态变量被存储在静态存储器中。这是罕见的使用静态变量以外声明为final,用作公共或私有常数。

·在程序启动时的静态变量被创建,在程序停止销毁。

·能见度类似于实例变量。然而,大多数静态变量声明为 public,因为它们必须可用于类的使用者。

·默认值是相同的实例变量。对于数字,默认值是0;为布尔值,它是假的,和对象引用,它为null。值可以在声明或构造函数中分配。另外值可以在特殊的静态初始化块进行分配。

·静态变量可以通过调用与类名来访问。 ClassName.VariableName.

·当定义的变量为 public static final ,那么变量的名称(常量)都是大写。如果静态变量是不公开的和最终的命名语法是相同的实例变量和局部变量。

 

二、常量const

1.常量代表程序运行过程中不能改变的值。

2.常量在程序运行过程中主要有2个作用:

         i. 代表常数,便于程序的修改(例如:圆周率的值)
         ii. 增强程序的可读性(例如:常量UPDOWNLEFTRIGHT分辨代表上下左右,其数值分别是1234

3.常量的语法格式和变量类型,只需要在变量的语法格式前面添加关键字final即可。在Java编码规范中,要求常量名必须大写。
    则常量的语法格式如下:
    final 数据类型 常量名称 = 值;
    final 数据类型 常量名称1 = 1, 常量名称2 = 2……常量名称n = n
    例如:
    final double PI = 3.14
    final char MALE=‘M’FEMALE=‘F’
    Java语法中,常量也可以首先声明,然后再进行赋值,但是只能赋值一次,示例代码如下:
 final int UP
    UP = 1

关于final详解
     final 用于声明属性(常量),方法和类,分别表示属性一旦被分配内存空间就必须初始化(不会有默认初始化,局部变量也是如此,默认初始化只有普通的非final成员属性,对于static(无final修饰)类变量,类连接时候有默认初始化,对于像private int a;在类实例化时,构造函数默认初始为0,总之,变量必须初始化后方可用,这是java的安全之一。                    final这个关键字的含义是这是无法改变的或者终态的
    那么为什么要阻止改变呢?
    java语言的发明者可能由于两个目的而阻止改变:
    1).效率问题:
    jdk中的某些类的某些方法,是不允许被用户覆盖的,设计者可能认为,所用方法已经是最好的方法,用户私自覆盖,或是由于疏忽而覆盖,就会影响JVM或是系统的系能;
    2). 设计所需:
    众所周知,有些情况必须使用final关键字,比如方法中的匿名内部类的参数传递

    【修饰变量】:
     final成员变量表示常量,只能被赋值一次,赋值后值不再改变。
    【修饰方法】:
     final方法不能被子类方法覆盖,但可以被继承。
    【修饰类】:
     final类不能被继承,没有子类,final类中所有方法都是final的。(String)


1.final修饰而没有被static修饰的类的属性变量只能在两种情况下初始化:(必须初始化)
a.在它被声明的时候赋值 
b.在构造函数里初始化
解释:                                                                                                                当这个属性被修饰为final,而非static的时候,它属于类的实例对象的资源(实例常量),当类被加载进内存的时候这个属性并没有给其分配内存空间,而只是 定义了一个变量a,只有当类被实例化的时候这个属性才被分配内存空间,而实例化的时候同时执行了构造函数,所以属性被初始化了,也就符合了当它被分配内存 空间的时候就需要初始化,以后不再改变的条件.

2.static修饰而没有被final修饰的类的属性变量只能在两种情况下初始化:(可以不初始化)
a.在它被声明的时候赋值
b.在静态或非静态快里初始化
解释:
当类的属性被同时被修饰为static时候,他属于类的资源(类变量),在类加载后,进行连接时候,分三步: 先验证;然后准备,准备时,先分配内存,接着默认初始化;可以进行解析。最后,进行类初始化,类初始化前,必须保证它的父类已经初始化了,所以最先初始化的是超类,对于接口,不必初始其父接口。类初始化时,它把类变量初始化语句及静态初始化语句放到类初始化方法中,所以,如果无此两种语句,也就没类初始化方法,而构造函数是在当类 被实例化的时候才会执行,所以用构造函数,这时候这个属性没有被初始化.程序就会报错.static块是类被加载的时候执行,且只执行这一次,所以在 static块中可以被初始化.

3.同时被finalstatic修饰的类的属性变量只能在两种情况下初始化:(必须初始化)
a.在它被定义的时候
b.在类的静态块里初始化 
c.特别对于初始化时候调用抛出异常的构造函数,初始时候注意,特别是在实现单例模式时(只能这么初始化)
如:
class A

private final static A a;
static
{
try
{
a=new A();
}catch(Exception e)
{
throws new RuntimeException(e);          //必须有,不然不能完成常量的正确初始化
}
}
private A() throws Exception{}
}
解释:
当类的属性被同时被修饰为staticfinal的时候,他属于类的资源(类常量),那么就是类在被加载进内存的时候(也就是应用程 序启动的时候)就要已经为此属性分配了内存,所以此时属性已经存在,它又被final修饰,所以必须在属性定义了以后就给其初始化值.而构造函数是在当类 被实例化的时候才会执行,所以用构造函数,这时候这个属性没有被初始化.程序就会报错.static块是类被加载的时候执行,且只执行这一次,所以在 static块中可以被初始化.

 

 java中的 final变量==常量

final变量的变与不变】:final表示变量的值或引用不变
    有人说final变量在赋值后就不可变,此变量可以是基本数据类型+String或者是对象
    那么这个不变到底指的是什么呢?
    这个不变指的是引用,是地址,而所引用的对象的内容仍然是可变的。注:如果为对象,注意此时类初始化条件
    就是说,这个final变量永远指向某个对象,是一个常量指针,而不是指向常量的指针。

final关键字的具体应用】:
    final+变量】:
        在实际应用中,这种形式是非常少见的。
        比如logger是可以的,但是貌似并不是非常实用,或许用户仍然希望通过setter来改变logger变量。
    static+final+变量】:
        常量。经常使用。
    final+方法】:
        JDK中常用,但是自己并未常用。
    final+类】:
        helper类经常使用。
    final用于匿名内部类的参数传递】:
        在多线程测试时,经常使用。
    final用于方法的参数】:
        并不常用。   

 

延伸:

interface里面的变量都是public static final 。所以你可以这样写:
public static final int i=10;
或则
int i=10;(可以省略掉一部分)
注意在声明的时候要给变量赋予初值

解释:
       首先你要弄清接口的含义.接口就是提供一种统一的协议,而接口中的属性也属于协议中的成员.它们是公共的,静态的,最终的常量.相当于全局常量.
       抽象类是不完全的类,相当于是接口和具体类的一个中间层.即满足接口的抽象,也满足具体的实现.
       如果接口可以定义变量,但是接口中的方法又都是抽象的,在接口中无法通过行为来修改属性。有的人会说了,没有关系,可以通过实现接口的对象的行为来修改接口中的属性。这当然没有问题,但是考虑这样的情况。如果接口A中有一个public访问权限的静态变量a。按照java的语义,我们可以不通过实现接口的对象来访问变量a,通过A.a = xxx;就可以改变接口中的变量a的值了。正如抽象类中是可以这样做的,那么实现接口A的所有对象也都会自动拥有这一改变后的a的值了,也就是说一个地方改变了a,所有这些对象中a的值也都跟着变了。如果可以修改值:这和抽象类有什么区别呢,怎么体现接口更高的抽象级别呢,怎么体现接口提供的统一的协议呢,那还要接口这种抽象来做什么呢?所以接口中不能出现变量,如果有变量,就和接口提供的统一的抽象这种思想是抵触的。所以接口中的属性必然是常量,只能读不能改,这样才能为实现接口的对象提供一个统一的属性。
       通俗的讲,你认为是要变化的东西,就放在你自己的实现中,不能放在接口中去,接口只是对一类事物的属性和行为更高层次的抽象。对修改关闭,对扩展(不同的实现implements)开放,接口是对开闭原则的一种体现。

 

 

三、Java的资料形态

java 变量与常量_第1张图片

1.整数

(1)Byte(8位):java.lang.Byte  (-2^7 ~ 2^7-1   -128 ~ 127)

(2)Short(16位):java.lang.Short(-2^15 ~2^15-1   -32768 ~ 32767)

(3)Int(32位):java.lang.Integer(-2^31 ~ 2^31-1   -2147483648 ~ 2147483647)

(4)Long(64位):java.lang.Long

(5)其他进制表示(0b1111 O1111 1111 Ox1111)

2.浮点数

(1)float:java.lang.Float(3.4028235E38 ~ 1.4E-45)

(2)Double:java.lang.Double(1.7976931348623157E308 ~ 4.9E-324)

float表示单精度浮点数在机内占4个字节,用32位二进制描述。
double表示双精度浮点数在机内占8个字节,用64位二进制描述。

double 和 float 的区别是double精度高,有效数字16位,float精度7位。但double消耗内存是float的两倍,double的运算速度比float慢得多,java语言中数学函数名称double 和 float不同,不要写错,能用单精度时不要用双精度(以省内存,加快运算速度)。

3.Boolean:java.lang.Boolean(frue/false)

4.Char:java.lang.Character(0 - 65535)

%b 真假

%h 杂凑码

%s 字符串

%c 字元

%d 十进制整数

%o 八进制整数

%x 十六进制整数

%e 科学计数法浮点数

%f 十进制浮点数

%g 科学计数法浮点数

%a 十六进制浮点数

 5.字串

(1)长度 int length():计算UNICODE内字元的个数

(2)连接

I.String concat(String str)——將 str 接到字串的後面

II.Str = str1 + str2——將 str1 跟 str2 做連接

(3)格式化

I.static String format(Locale l, String format, Object... args)

II.static String format(String format, Object... args)

(4)分割:將原字串利用 regex 拆開存入字串陣列,然後回傳這個字串陣列

String[] split(String regex)

String[] split(String regex, int limit)

(5)取得子字串:

String substring(int beginIndex, intendIndex)——回傳從 beginIndex 到 endIndex 之間的子字串

String substring(int beginIndex)——回傳從 beginIndex 到結尾的子字串

CharSequence subSequence(int beginIndex, int endIndex)——回傳從 beginIndex 到 endIndex 之間的CharSequence 型態物件

String trim() 回傳去除首尾空白符號的子字串

(6)字串寻找:

int indexOf(int ch) ——回傳第一個 ch 字元的索引值

int lastIndexOf(int ch) ——回傳最後一個 ch 字元的索引值

int indexOf(int ch, int fromIndex)——回傳 fromIndex 之後的第一個 ch 字元的索引值

int lastIndexOf(int ch, int fromIndex)——回傳 fromIndex 之前的最後一個 ch 字元的索引值

int indexOf(String str)—— 回傳第一個子字串 str 開始的的索引值

int lastIndexOf(String str) ——回傳最後一個子字串 str 開始的的索引值

boolean contains(CharSequence s) ——判斷字串中是否包含 s

(7)字串替换:

String replace(char oldChar, char newChar) ——將 oldChar 字元以 newChar 置換

String replace(CharSequence target, CharSequence replacement) ——將 target 子字串以 replacement 置換

String replaceAll(String regex, String replacement) ——將符合 regex 置換成 replacement

String replaceFirst(String regex, String replacement) ——將第一個符合 regex 的子字串置換成replacement

(8)字串比较:

boolean endsWith(String suffix)

判斷字串是否以 suffix 結尾

boolean startsWith(String prefix)

判斷字串是否以 prefix 開頭

boolean startsWith(String prefix, int offset)

判斷從 offset 開始的子字串是否為 prefix

int compareTo(String anotherString)

逐字元比較原字串與 anotherString ,若無不同,也就是兩個字串中的每

個字元都相同就回傳 0 ,若有不同則回傳長度差或第一個不同字元的

Unicode 差值

int compareToIgnoreCase(String str)

逐字元比較原字串與 anotherString ,不考慮大小寫的分別,若無不同,

也就是兩個字串中的每個字元都相同就回傳 0 ,若有不同則回傳長度差或第

一個不同字元的 Unicode 差值

boolean equals(Object anObject)

判斷字串是否與 anObject 相同

boolean equalsIgnoreCase(String anotherString)

判斷字串是否與 anotherString 相同,不考慮大小寫的分別

boolean regionMatches(int toffset, String

other, int ooffset, int len)

判斷從 toffset 開始長度為 len 的子字串,是否與 other 從 ooffset開始

長度為 len 的子字串相同

boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)

判斷從 toffset 開始長度為 len 的子字串,是否與 other 從 ooffset開始

長度為 len 的子字串相同, ignoreCase 提供是否要忽略文大小寫字母

boolean matches(String regex)

判斷字串是否符合 regex

 

(9)字串大小写控制:

String toLowerCase() 將字串中所有英文字母改為小寫

String toUpperCase() 將字串中所有英文字母改為大寫

6.Adf

 

四、资料形态转换

1.自动转换(小到大):byte - short - int - long - float - double

2.强迫转换(大到小):反过来。。

 

五、命名规则

1.系统保留字

abstract  boolean  break  byte  case  catch char class const continue default do double else extends final finally float for goto if implements import instanceof int interface long native new package private protected public return short static strictfp super switch synchronized this throw throws transient try void volatile while

2.命名规范

3.

 

六、阵列

 

你可能感兴趣的:(JAVA)