数据类型与变量

一、字面常量

常量即程序运行期间,固定不变的量称为常量。

public class Demo{
public static void main(String[] args){
System.Out.println("hello world!");
System.Out.println(100);
System.Out.println(3.14);
System.Out.println('A');
System.Out.println(true);
System.Out.println(false);
}
}

字面常量的分类:

  1. 字符串常量:由""括起来的,比如“12345”、“hello”、“你好”。
  2. 整形常量:程序中直接写的数字(注意没有小数点),比如:100、1000
  3. 浮点数常量:程序中直接写的小数,比如:3.14、0.49
  4. 字符常量:由 单引号 括起来的当个字符,比如:‘A’、‘1’
  5. 布尔常量:只有两种true和false
  6. 空常量:null(后面了讲)

注意:字符串、整形、浮点型、字符型以及布尔型,在Java中都称为数据类型。

二、数据类型

在这里插入图片描述

1、数据类型的表示范围

定义变量:数据类型+变量
数据类型范围: -2(n-1) ~ 2(n-1) -1(n代表bit位数)
在这里插入图片描述

  • 不论是在16位系统还是32位系统,int都占用4个字节,long都占8个字节
  • 整形和浮点型都是带有符号的
  • 整型默认为int型,浮点型默认为double
  • 字符串属于引用类型,该中类型后序介绍。

优点:可移植性高
在这里插入图片描述
在这里插入图片描述

2、特殊用法以及注意事项

1. 包装类:

包装类可以看做是数据类型的plus版本,具体的区别需要以后讲解。
int—Integer 、char —Character、其余的就是数据类型的首字母大写。
而类中才会有方法,所以想使用方法需要:数据类型的包装类.方法
计算数据类型所能表示的范围:数据类型的包装类.length
在这里插入图片描述

2. final关键字

相当于c语言中的const,修饰的变量是不能被修改的。

        //const --- final: 被final修饰的变量叫做常量就不能进行修改了,一般将final修饰的变量写成大写
        final int SIZE = 100;
//        SIZE = 10;//报错
3. 局部变量未初始化会编译错误,而不会分配随机值
        //如果一个变量没有初始化会编译报错,并不会赋值为随机值
        int c;
//        System.out.println(c);报错
4. 类型转换

分为两种自动类型转换(隐式) 和 强制类型转换(显式)
1、自动类型转换
代码不需要经过任何处理,在代码编译时,编译器会自动进行处理。特点:数据范围小的转为数据范围大的时会自动进行

int a = 100;
long b = 10L;
b = a;   // a和b都是整形,a的范围小,b的范围大,当将a赋值给b时,编译器会自动将a提升为long类型,然后赋值
a = b;   // 编译报错,long的范围比int范围大,会有数据丢失,不安全

float f = 3.14F;
double d = 5.12;
 
d = f; // 编译器会将f转换为double,然后进行赋值
f = d; // double表示数据范围大,直接将float交给double会有数据丢失,不安全

2、强制类型转换

强制类型转换:当进行操作时,代码需要经过一定的格式处理,不能自动完成。特点:数据范围大的到数据范围小
的。

int a = 10;
long b = 100L;
b = a;        // int-->long,数据范围由小到大,隐式转换
a = (int)b;   // long-->int, 数据范围由大到小,需要强转,否则编译失败
 
float f = 3.14F;
double d = 5.12;
d = f;        // float-->double,数据范围由小到大,隐式转换
f = (float)d; // double-->float, 数据范围由大到小,需要强转,否则编译失败
 
a = d;   // 报错,类型不兼容
a = (int)d;   // int没有double表示的数据范围大,需要强转,小数点之后全部丢弃
 
byte b1 = 100;        // 100默认为int,没有超过byte范围,隐式转换
byte b2 = (byte)257;  // 257默认为int,超过byte范围,需要显示转换,否则报错
 
boolean flag = true;
a = flag;   // 编译失败:类型不兼容
flag = a;   // 编译失败:类型不兼容

注:

  1. 不同数字类型的变量之间赋值, 表示范围更小的类型能隐式转换成范围较大的类型
  2. 如果需要把范围大的类型赋值给范围小的, 需要强制类型转换, 但是可能精度丢失
  3. 将一个字面值常量进行赋值的时候, Java 会自动针对数字范围进行检查
  4. 强制类型转换不一定能成功,不相干的类型不能互相转换

一个有趣的强转:虽然强转是编译可实现的,但是某些情况会"爆炸"

//强转风险:精度丢失  --  -128不建议
        byte p = 10;
        int r = 128;
        byte p = (byte)r;
        System.out.println(p);

在这里插入图片描述

数据类型范围计算方法

为什么可以像上面一样计算范围,这里有一妙计:
1、画一个圆,一分为二
2、左边-1到负数最大值,右边0到正数最大值
3、向右转是+,向左转是-。

原因:数据内存存储决定的
在这里插入图片描述

原本-128原码和补码都是 1 1000 0000,按计算方法去掉高位溢出位,也就是 1000 0000。

5、类型提升

1、不同类型的数据混合运算, 范围小的会提升成范围大的.
2、 对于 short, byte 这种比 4 个字节小的类型, 会先提升成 4 个字节的 int , 再运算.

  1. int与long之间:int会被提升为long
int a = 10;
long b = 100L;
int c = a + b;//会报错,a自动提升为long类型
long d = a + b;//编译成功
  1. byte与byte的运算:byte整形提升为int
byte b2 = 10;
byte b3 = 20;
int c1 = b2+b3;
byte c2 = (b2+b3);//编译报错b2+b3整形提升为int,大转小,要强转

不足四字节的类型会先整形提升为int,因为计算机cpu读写内存数据是以4字节为单位的,为了方便硬件,会将字节数低于4字节的数据类型先整形提升为int,在进行计算。(比如byte、short)

三、数据类型

1. 整形

		System.out.println(Long.MAX_VALUE);
        System.out.println(Long.MIN_VALUE);
        long l = 100L;//最好使用大写,不建议使用小写
        System.out.println(l);

        //2个字节
        short s = 10;
        System.out.println(Short.MAX_VALUE);
        System.out.println(Short.MIN_VALUE);
        //字节型 -128  127
        byte b = 127;
        System.out.println(b);
        System.out.println(Byte.MAX_VALUE);
        System.out.println(Byte.MIN_VALUE);

思考:byte、short、int、long都可以定义整形变量,为什么要给出4中不同类型呢?
这就好比买衣服时的尺码:
在这里插入图片描述

2. 浮点型

  1. int 除以 int 的值仍然是 int(会直接舍弃小数部分)。如果想得到 0.5, 需要使用 double 类型计算
double a = 1.0;
double b = 2.0;
System.out.println(a / b);   // 输出0.5
  1. double 类型的内存布局遵守 IEEE 754 标准(和C语言一样),浮点数与整数在内存中的存储方式不同,不能单纯使用的2n形式来计算
double num = 1.1;
System.out.println(num * num);  // 输出1.21吗?
    
// 执行结果
1.2100000000000002

1.21在计算机中不能精确保存–0.5 0.25 0.125 …(小数点后n位的位权)这些数中的某些数加不到正好是0.1,但是可以精确到小数点后几位,只是不能精确表示每一位。

  1. 单精度浮点型
float num = 1.0f;    // 写作 1.0F 也可以
System.out.println(num);

float 类型在 Java 中占四个字节, 同样遵守 IEEE 754 标准. 由于表示的数据精度范围较小, 一般在工程上用到浮点数
都优先考虑 double, 不太推荐使用 float. float的包装类型为Float

3、布尔类型

布尔类型没有明确说明占用几个字节
在这里插入图片描述

4、字符类型

使用的字符集是unicode字符集,一个字符占两个字节。

        char ch1 = 'a';
        char ch2 = '高';//两个字节
        System.out.println(ch1);
        System.out.println(ch2);
        //Character为char 的包装类型,具体与基本数据类型区别以后讲解

关于字符编码方式的讨论, 参见

上节提到javac编译出现乱码,在执行 javac 时加上 -encoding UTF-8 选项即可

Test.java:3: 错误: 未结束的字符文字
        char ch = '鍛?';
                  ^
javac -encoding UTF-8 Test.java

5、 字符串类型

加号 ----拼接 、求和

加号可以拼接字符串

//字符串类型  加号可以拼接字符串
        String str1  = "hello";
        String str2 = "world";
        System.out.println(str1 +" "+ str2);
        System.out.println(str1.length());
        System.out.printf("a = %s\n",str1);//同样也可以使用printf函数和c语言一样的用法

字符串拼接和加法区分

int m1 = 10;
int m2 = 20;
System.out.println(m1 + m2 + " = m1 + m2");//30 = m1 + m2;第一个加号求和,第二个加号拼接
System.out.println("m1 + m2 = " + m1 + m2);//m1 + m2 = 1020 全是拼接

在有些情况下,需要将字符串和整形数字之间进行转换:
本节对只是对字符串进行简单的介绍,大家能够正常使用即可,后序会详细给大家介绍。

1、int转String
//整数转换字符串
        int a = 10;
        String str = a + "";
        System.out.println(str);
        System.out.println("==========");
        String str1 = String.valueOf(a);//包装类里面的方法
        System.out.println(str1);
2、 String 转成 int
		String str1 = "100";
        int a = Integer.parseInt(str1);//底层是调用了valueof
        int b = Integer.valueOf(str1);
        System.out.println(a);
        System.out.println(b);

四、运算符、逻辑控制、方法

这里只提及和c语言不同的点

1. 0不能做除数:除零异常,在java中被称作算数异常

     System.out.println(5/0);

在这里插入图片描述

2. 小数可以作为被取余的数

System.out.println(12.5%2);

在这里插入图片描述

3. 运算符两侧操作数类型不一致时候,向大类型提升

     System.out.println(1+2.0);

在这里插入图片描述

4. +=运算符会帮你进行类型转换

     int c = 10;
     long d = 20;
//     c = c + d;//c的类型精度低于d
     c += d;//这个运算符就可以帮你进行类型提升
     System.out.println(c)

5. 逻辑与、或的两侧、非的右侧必须是布尔表达式

6. 当按位与、或两侧为表达式的时候,也可以作为逻辑运算符来使用。但是不会出现短路现象

//如果发生短路,那么就不会执行后面的语句---结果是报错了
        System.out.println(10 > 2 & 10/0 == 0);
        System.out.println(10 < 2 | 10/0 == 0);

在这里插入图片描述

7. 左移、有符号右移、无符号右移(n/2x针对的是正数)

在这里插入图片描述

//无符号右移,为超大整数
        byte a = -1;
        System.out.println(a >>> 1);
        System.out.println(a >> 1);

8. 表达式是不能单独存在的,其产生的结果必须要被使用

boolean b = true == true ? false == true  ? false : true : true;
        System.out.println(b);

这个表达式运算结果是 true,你做对了嘛

boolean b = (true == true) ? (false == true  ? false : true ): true;
        System.out.println(b);

9. 顺序、选择、循环,所有条件表达式必须是布尔表达式(if()、while()),选择语句只能选中一个条件为真执行,注意花括号写法。

10. float、double、long、boolean都不能作为switch的参数、并且不能为复杂表达式a > 1这种 ,像这样的String、int、枚举类型✅️

//float、double、long、boolean都不能作为switch的参数、并且不能为复杂表达式a > 1这种
        //String、int、枚举类型✅️
        String str = "nihao";
        switch(str){
            case "nihao":
                System.out.println("nihao");
                break;
            case "zao":
                System.out.println("zao");
                break;
            default:
                System.out.println("hello");
                break;

11. 求1!+2!+…+5!

—单独求各个数字的阶乘,在使用循环将其累加起来
在这里插入图片描述

		int j = 1;
        int l_ret = 0;
        while(j <= 5){
            int ret = 1;
            int i = 1;
            //求i = 1-5之间的阶乘
            while(i <= j)
            {
                ret *= i;
                i++;
            }
            //把每一个的结果都加起来
            l_ret += ret;
            j++;
        }
        System.out.println(l_ret);

12. 调试相关按键(注意:条件断点要打在条件语句上)

在这里插入图片描述

13.使用break和continue在1-100之间找出既能被3整除,也能被5整除的数字

在使用continue的时候一定不要忘记在其上补充一句变量改变的语句,否则会造成死循环

//使用break和continue在1-100之间找出既能被3整除,也能被5整除的数字
    int i = 1;
    while(i <= 100){
        //能被3和5整除就是能被15整除的。
        if(i % 15 != 0){
            i++;//这里一定不能忘记i++,否则会造成死循环
            continue;
        }
        System.out.print(i + " ");
        i++;
    }

13. for循环的便捷实用,fori回车,第一次修改i变量,第二次修改条件。

10.fori == for(int i = 0;i<10;i++)
a.sout == system.out.println(a);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

14. 输入输出

我们可以在帮助手册中查到输入的使用方法:
在这里插入图片描述

一般在java中很少使用输入:

	import java.util.Scanner;//输入scanner会自动帮你加上

		void main() {
        Scanner scanner = new Scanner(System.in);
        //输入一行字符串--两种方式
        String s = scanner.nextLine();//读入一行字符串,遇到空格不会结束
        System.out.println(s);
        String s1 = scanner.next();//读入,遇到空格便停下
        System.out.println(s1);
        System.out.print("请输入你的姓名:");
        String n =  scanner.nextLine();
        System.out.println("你好,"+ n);
        System.out.print("请输入年龄:");
        int age = scanner.nextInt();
        System.out.println("您的年龄:"+age);
        System.out.print("请输入你的薪水:(w)");
        float salary = scanner.nextFloat();
        System.out.println("您的薪水:"+salary);
    }

在这里插入图片描述

halou nihao
halou nihao
halou nihao
halou
请输入你的姓名:你好, nihao
请输入年龄:18
您的年龄:18
请输入你的薪水:(w)20
您的薪水:20.0

如果是这样呢?

		Scanner scanner = new Scanner(System.in);
        System.out.print("请输入年龄:");
        int age = scanner.nextInt();
        System.out.println("您的年龄:"+age);
        //输入一行字符串--两种方式
        String s = scanner.nextLine();//读入一行字符串,遇到空格不会结束
        System.out.println(s);
        System.out.print("请输入你的薪水:(w)");
        float salary = scanner.nextFloat();
        System.out.println("您的薪水:"+salary);
请输入年龄:18
您的年龄:18

请输入你的薪水:(w)20
您的薪水:20.0

其实是读入了字符串的,因为你在输入18的时候按了回车,就把回车读进去了。
解决办法:

在年龄语句后面加上一个读字符串语句即可scanner.nextLine();

循环输入:ctrl+D停下来

public static void main(String[] args){
    Scanner sacnner = new Scanner(System.in);
    while(sacnner.hasNextInt()){ //有新的正数就读进来
        int n = sacnner.nextInt();
        System.out.println(n);
    }
}

在这里插入图片描述

输出:格式化输出是和c语言一致的。

		System.out.println("换行输出");
        System.out.print("不换行输出");
        System.out.printf("%2f",10.0f);//格式化输出

在这里插入图片描述

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐