Java变量

257 阅读7分钟

Java变量

变量概述

每个变量都有一个对应的数据类型以及变量名

变量名,类名,方法名等等标识符命名规则

  1. 组成:由26个字母大小写,0-9,- 或 $ 组成,不可以以数字为开头命名,中间不能留有空格

  2. 不可以使用关键字和保留字

    image-20220113145556828

  3. 区分大小写,长度无限制

变量的声明

// 数据类型 + 变量名,变量名...
int age;
String name;
String school,grade;
// 注意变量名不要是java保留字(关键字)

变量初始化

// 成员变量可以不用赋值 有默认初始化
// 局部变量必须初始化(两种方式)
int num;
num = 10;
int num2 = 10;、
// jdk10之后,可以不需要声明类型(从变量的初始值来判断类型)
var  i = 10;

数据类型(重点)

java是一种强制类型语言,每一种数据都定义了明确的数据类型,在内存中分配了不同大小的内存空间(字节)

image-20211219160638668

细节:字符串本质是类,属于引用数据类型

整数的类型

类型占用存储空间范围
byte 字节1字节-128 ~ 127
short 短整型2字节-2^15 ~ 2^15-1
int 整型4字节-2^31 ~ 2^31-1
long 长整型8字节-2^63 ~ 2^63-1

1字节(byte) = 8 位(bit)

bit 计算机中的最小的存储单位 byte 计算机中基本存储单位

整数型注意细节

  1. 数值常量值默认为int类型

  2. 长整型后面有一个后缀(L或l)

    // 自动转型
    Long num = 1000; int -> long
    // 赋值
    Long num2 = 40000000L;
    // 反问:那为什么需要特定后缀L,不是自动转型不就可以了吗?
    // 如果你的数值在int范围内,那自然都没事;但是当你要赋值一个int范围外的数字又该怎么做呢?
    
  3. 十六进制数值前缀:0X或者0x;八进制数值前缀:0 ;二进制数值前缀:0b 或者 0B (记住是数字0)

    // 十六进制
    OXCAFE
    // 八进制
    010
    // 二进制
    0B1001
    0B1_0000_0000 // jdk7以后 编译时会自动去除下划线
    
  4. 注意java没有任何无符号形式的关键字(unsigned)但是提供了方法处理

浮点类型

浮点数字 = 符号位 + 指数位 + 尾数位 (尾数位可能丢失,造成精度的损失)

类型占用存储空间范围
float (单精度)4字节-3.403E38 ~ 3.403E38-1
double (双精度)8字节-1.798E308 ~ 1.798E308-1

备注:E38 指的是 10^38

浮点数注意细节

  1. 浮点型常量默认为double类型

  2. float 后面需要添加f 或 F,double后面可加可不加

    float num1 = 1.0; // 错误
    double num2 = 1.1; // 正确
    float num3 = 1.2F; // 正确
    double num4 = 1.3f; // 正确
    
  3. 浮点型常量的表示形式

    double num = 1.0; // 十进制数形式 1.0f  .512 == 0.512(小数点必须在可以省略0)
    double num5 = 5.12e2; // 科学计数法 5.12e2 == 512  5.12E-2 == 0.0512
    
  4. 通常情况下我们使用double 精度高

    double num = 1.23456789123f;
    float num1 = 1.23456789123f;
    System.out.println(num);  // 1.23456789123
    System.out.println(num1);  // 1.2345679
    
  5. 比较 小数数字是否相等时要注意:最好不要直接去比较两个浮点数是否 ==,最好是两个浮点数的差值绝对值在某个精度范围内来进行比较(如0.000001)

    double num = 8.1 / 3;
    double num1 = 2.7;
    System.out.println(num); // 2.6999999999999997 
    System.out.println(num1); //2.7
    ​
    if(Math.abs(num - num1) < 0.000001){
        System.out.println("相等");
    }
    
  6. 对于使用strictfp关键字标记的方法必须严格的浮点计算来生成结果,好处:不仅让浮点数运算更加精确,而且不会因为不同硬件平台所执行而效果不同;坏处:降低性能

    // 主方法下的所有浮点数都严格按照IEEEE-754标准进行运算
    public static strictfp void main(String[] args){}
    

字符类型

类型占用存储空间表示
char2字节表示单个字符

字符型注意细节

  1. 字符常量是用单引号(’‘)括起来的单个字符

    char c = 'n';
    
  2. 单引号里面可以放入转义字符(虽然有两个字符,但是它是表示一个字符的 比如 // 表示 / )

    char ch = '//'
    
  3. char 的本质就是一个整数(unicode表) (注意:字符 --> 数字 unicode 数字 --> 字符 )

    // unicode 编码
    'a' --  97
    // char 类型字符可以进行加减 但是注意超出范围的问题
    'a' + 10 -- 107
    

字符在计算机里的存储方式

存储:‘a’ ==> 97 ==> 二进制数(11000001) ==> 存储

读取: 二进制(11000001) ==> 97 ==> 'a' ==> 读取

字符编码表

  • ASCll编码表,一个字节表示,ASCII实际上可以表示256个字符,但是只使用了128个
  • Unicode编码表 ,固定两个字节表示字符(字符和汉字统一都是占用2个字节)
  • utf-8编码表,大小可变的编码(字母使用1个字节,汉字使用3个字节)
  • GBK编码,大小可变的编码(字母使用1个字节,汉字使用2个字节)
  • big5编码,繁体字,台湾,香港(了解)

布尔类型

常用于条件判断语句 if - else while

类型占用存储空间表示
boolean1字节+ / false

注意:布尔类型不能和整数型相互转换(这里和c/c++不同)

数据类型转换

自动类型转换

精度小的数据类型自动转换为精度大的数据类型

image-20220111140545230

自动类型转换相关的注意细节

  1. 当一个二元运算符连接两个值时,先将两个操作数转换成同一类型的数据进行计算(转换成操作数两边范围最大的数据类型)

    // 伪代码 顺序:double -> float -> long -> int -> short -> byte
    //             double -> float -> long -> int -> char
    if(两个操作数中有一个是double类型数据){
        另一个操作数也会强制转换成double类型数据
    }else if(两个操作数中有一个是float类型数据){
        另一个操作数也会强制转换成float类型数据
    }... // 依次下去
    
  2. (byte,short)和 char 之间不会自动转换

  3. 注意赋值区别(具体数值赋值和变量赋值)

    // 具体值赋值会先进行范围的判进行赋值
    char c = 10000; 
    short s = 'a';
    byte b = 'b';
    // 变量赋值就是依据自动类型转换或者强制类型转换
    c = (char)s;
    s = (short)c;
    
  4. 整数赋值和浮点数赋值的注意点

    // 整数之间的赋值
    byte n = 10; // 具体数值赋值,先进行判断该数值是否在byte范围,如果在编译就不会出错,便会赋值
    int n1 = 10;
    n = n1; // int类型变量无法直接赋值给byte类型(可以进行强制类型转换)
    ​
    // 小数之间赋值 
    float f = 10.0; // 错误,float中将无法进行比较,本来都是一个估算值,无法进行比较范围,因此10.0是double类型无法自动转型为float
    
  5. byte,char,short 三者进行计算,在计算时首先转换成int类型数据(变量计算都会转换成int类型,不管是否是同类型数据相加减)

  6. boolean 数据类型不参与类型转换

强制类型转换

概念: 自动类型转换的逆过程,将范围大的数据类型转换成范围小的数据类型,使用时需要在变量或者具体值前面加()

好处: 根据程序员的意愿进行修改 坏处: 范围超出了想要转换的数据类型,会导致溢出问题

// 例如 double ==> float
float f = (float)10.0;

强制类型转换的注意细节

  1. 强制符号只针对最近的操作数有效,往往会使用小括号来提升优先级

    int n = (int)10*3.5+12*2.3; // 错误
    int n = (int)(10*3.5+12*2.3); // 正确
    
  2. 注意区别 i++ 和 i = i+1的区别

    // 直接上代码
    class test{
        public static void main(String[] args) {
            byte j = 10;
            j++;
            short k = 11;
            k += 1;
            int i = 11;
            i = i + 1;
        }
    }
    // 反编译看细节
    class test {
      test();
        Code:
           0: aload_0
           1: invokespecial #1                  // Method java/lang/Object."<init>":()V
           4: return
    ​
      public static void main(java.lang.String[]);
        Code:
           0: bipush        10  // 将数值10压入栈
           2: istore_1   // 栈中弹出一个数(10),赋值给局部变量j(_1表示赋值给第一个局部变量,即j)
           3: iload_1    // 将局部变量j(_1表示第一个局部变量,即j)的值入栈,此时栈顶的值为10
           4: iconst_1   // 将常量1(_1)压入栈中
           5: iadd       // 相加常量和局部变量j => 11
           6: i2b        // 注意!! 强制类型转换 int -> byte
           7: istore_1
           8: bipush        11
          10: istore_2  //  栈中弹出一个数(11),赋值给局部变量k(_2表示赋值给第二个局部变量,即k)
          11: iload_2
          12: iconst_1
          13: iadd
          14: i2s        //  注意!! 强制类型转换 int -> short
          15: istore_2
          16: bipush        11 
          18: istore_3
          19: iload_3
          20: iconst_1
          21: iadd
          22: istore_3
          23: return
    }
    // 总结
    i++ && i += 1 // 会进行强制类型转换成原来的类型
    i = i+1  // 如果i是byte或者short类型都不能通过编译,因为i+1会自动转换成int类型,int类型必须通过强制类型转换才可以转换成short或者byte类型
    

基本数据类型和String类型的转换

  1. 将基本数据类型+"" ==> String类型

    String s = 10 + "";
    
  2. 通过基本数据类型的包装类调用parseXX方法

    String s = "2"
    Integer.parseInt(s);
    Double.parseDouble(s);
    Float.parseFloat(s);
    Short.parseShort(s);
    Long.parseLong(s);
    Boolean.parseBoolean("true");
    Byte.parseByte(s);
    ​
    // char 根据索引来判断
    String str = "123456789";
    char c  = str.charAt(0);