Java(基础02)
参考视频:Java基础03:数据类型讲解(狂神)
1. 数据类型讲解
- 强类型语言:例如java,.net,c/c++等,要求变量的使用要严格符合规定,所有变量都必须先定义后才能使用。
- 弱类型语言:例如js,vb,php等,有时很方便,有时却极易出错。
Java的数据类型分为两大类:
- 基本类型(primitive type)
- 数值类型
- 整数类型
- byte:占1个字节,范围:-128-127
- short:占2个字节,范围:-32768-32767
- int:占4个字节,范围:-2147483648-2147483647
- long:占8个字节,范围:-9223372036854775808-9223372036854775807
- 浮点类型
5. float:占4个字节
6. double:占8个字节 - 字符类型:
7. char:占2个字节
- 整数类型
- boolean类型:
8. boolean:占1位,其值只有true和false两个
- 数值类型
- PS:查询范围是多少的方法:
- 输入对应类型的包装类型。例如int的包装类型为Integer,byte的包装类型为Byte,等等。
- ctrl+鼠标左键,点击Integer或者Byte,进入底层,即可查询范围。
public class Demo01 {
public static void main(String[] args) {
//八大基本数据类型
//整数类型
int num1 = 10; //常用
byte num2 = 20;
short num3 = 30;
long num4 = 30L; //强调是long类型时,要加L或l
//小数(浮点数)类型
float num5 = 3.14F; //强调是float类型时,要加F或f
double num6 = 3.1415926;
//字符类型
char name = '国';
//布尔类型(值为:true和false)
boolean flag = true;
//String类型(即字符串类型,属于引用类型,且不是关键字)
String name2 = "中国cn666";
int String = 0;
System.out.println(String);
System.out.println(name2);
}
}
占1个字节 | 占2个字节 | 占4个字节 | 占8个字节 |
---|---|---|---|
byte | short | int | long |
boolean(?) | char | float | double |
- Q:什么是字节?什么是字符?
- 位(bit):是计算机 内部数据 存储的最小单位,例如11001100是一个八位二进制数。
- 字节(byte):是计算机中 数据处理 的基本单位,习惯上用大写 B 来表示
- 1B(byte) = 8b(bit),即1字节 = 8位
1bit,即1位
1byte = 8bit,即1B = 8b
1024B = 1KB
1024KB = 1M
1024M = 1G
1024G = 1T
… …- 字符:是指计算机中使用的字母、数字、字和符号
- ★Q:Java中boolean类型到底占用多少字节?多少位?
- 占1位
由于boolean类型的值只有true和false两种逻辑值,在编译后会使用1和0来表示,而这两个数在内存中只需要1位,即1bit即可存储。位,是计算机最小的存储单位。- 占1个字节
虽然在编译后1和0只占用1位空间,但是计算机处理数据的最小单位是1个字节,1个字节等于8位,所以实际存储方式为:用1个字节的最低位存储,其他7位用0填补。若值为true则存储的二进制为:0000 0001,若值为false则存储的二进制为:0000 0000。- 占4个字节(单独使用)/1个字节(在数组中使用)
《Java虚拟机规范》一书中描述:“虽然定义了boolean这种数据类型,但是只对它提供了非常有限的支持。在Java虚拟机中没有任何供boolean值专用的字节码指令,Java语言表达式所操作的boolean值,在编译之后都使用Java虚拟机中的int数据类型来代替,而boolean数组将会被编码成Java虚拟机的byte数组,那么每个boolean元素就占8位”。综上所述,boolean类型单独使用占4个字节,而在数组中使用却占1个字节。
显然第三种说法更有说服力,那为什么虚拟机要用int代替boolean,而不用byte或者short,不是更节省内存空间吗?经查阅资料发现,使用int的原因是,对于当下32位的处理器(cpu)来说,一次处理数据是32位(不是指32/64位系统,而是指cpu硬件层面),具有高效存取的特点。
小结:
根据 http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html 官方文档的描述:
boolean: The boolean data type has only two possible values: true and false. Use this data type for simple flags that track true/false conditions. This data type represents one bit of information, but its “size” isn’t something that’s precisely defined.
布尔类型:boolean数据类型只有两个可能的值:true和false。将此数据类型用于跟踪真/假条件的简单标志。这种数据类型代表一小部分信息,但是其“大小”并不是精确定义的。
可以看出,boolean类型没有给出精确定义,《Java虚拟机规范》给出了单独使用为4个字节,以及在boolean数组中使用为1个字节的两种定义,具体还要看虚拟机实现是否按照规范,所以1个字节或者4个字节都有可能。这其实是运算效率和存储空间之间的博弈,两者都很重要。
- 引用类型(reference type)
- 类(例如String类)
- 接口
- 数组
2. 数据类型扩展及面试题讲解
- 具体讲解参考 数据类型扩展及面试题讲解(狂神)
public class Demo02 {
public static void main(String[] args) {
//整数拓展:进制 二进制0b 十进制 八进制0 十六进制0x
int i0 = 0b10;//二进制,由0-1组成,0b开头
int i1 = 010;//八进制,由0-7组成,0开头
int i2 = 10;//十进制,由0-9组成
int i3 = 0x10;//十六进制,由0-15组成,其中10-15必须用a-f或A-F表示
//输出结果为10进制
System.out.println(i0);
System.out.println(i1);
System.out.println(i2);
System.out.println(i3);
System.out.println("========================================");
//========================================
//1. 浮点数拓展 银行业务用什么类型表示 钱?
//答:使用BigDecimal 是一个数学工具类
//========================================
//float? 可表示的字长有限 离散 舍入误差 大约(接近但不等于)
//double?
//★尽量避免使用浮点数进行比较!
float f = 100.1f;
double d = 100.1;
System.out.println(f);
System.out.println(d);
System.out.println(f==d);//判断f和d是否相等,结果为false
float f2 = 23333333f;
float f3 = f2-1;
System.out.println(f2);
System.out.println(f3);
System.out.println(f2==f3);//结果为true
//========================================
//2. 字符拓展
//========================================
System.out.println("========================================");
char c1 = 'a';
char c2 = '中';
System.out.println(c1);
System.out.println((int) c1);//强制转换
System.out.println(c2);
System.out.println((int) c2);//强制转换
//所有的字符本质还是数字
//涉及到编码 例如Unicode编码 占2个字节
// 该编码最多可以表示65536(即2^16)个字符
// (例如早些年的Excel表最多就这么长),现在该编码可以表示更多字符
// Unicode有一张表:其中97='a' 65='A' 20013='中' ... ...
// Unicode的转义表示的范围:U0000-UFFFF
char c3 = '\u0061';//表示'a',其中\+u是转义字符的一种
System.out.println(c3);
//转义字符
//\t 制表符(tab)
//\n 换行符(enter)
//... ...
System.out.println("========================================");
System.out.println("Hello\tWorld\n!!!");
System.out.println("========================================");
String s1 = new String("Hello World");
String s2 = new String("Hello World");
System.out.println(s1==s2);//结果为false
String s3 = "Hello World";
String s4 = "Hello World";
System.out.println(s3==s4);//结果为true
//后面学对象时,将从内存进行分析。
//布尔值扩展
System.out.println("========================================");
boolean flag = true;
if (flag==true){ }//新手
if (flag){ }//老手
//less is more!代码要精简易读
}
}
遇到的一个错误:
java: 非法的 Unicode 转义
资料显示:Java是允许在注释以及代码中使用\u开头的Unicode转义字符的,但是要求转义必须有效,否则编译器会报告错误。
注释中有一行为 //表示’a’,其中 \ + u 是转义字符的一种 修改前写的是\u…,无法匹配到字典,所以抛出错误。
小结:
Java是允许在注释以及代码中使用\u开头的Unicode转义字符的,但要求转义必须有效,否则编译器会报错。(注释包含单行,多行,文档注释)。
3. 类型转换
-
由于Java是强类型语言,所以当进行某些运算的时候,需要用到类型转换。
-
运算中,如果数据类型不同,会先转换为同一类型,然后进行运算,自动转换方向如下(小数的优先级大于整数):
-
低 ---------------------------------------------------------> 高
byte,short,char → int → long → float → double
数据类型转换分为两种:
- 强制类型转换
- 自动类型转换
示例1如下:
public class Demo03 {
public static void main(String[] args) {
int i = 128;//定义变量
double d = i;//自动转换(低→高)
byte b = (byte) i;//强制转换(高→低)
System.out.println(i);//128
System.out.println(d);//128.0
System.out.println(b);//-128,错误输出是由于内存溢出,因为byte范围为[-128,127]
/*
注意点:
1. 布尔值不能进行转换。
2. 不能把对象类型转换为不相干的类型。
3. 在把高容量转换到低容量类型的时候,是强制转换。
4. 转换的时候可能存在内存溢出问题,或者精度问题!(如下)
*/
System.out.println("====================");
System.out.println((int)99.9);//99(不是四舍五入)
System.out.println((int)-99.9f);//-99(不是四舍五入)
System.out.println("====================");
char c = 'a';
int i1 = c+1;
System.out.println(i1);//98
System.out.println((char)i1);//b
}
}
示例2如下:
public class Demo06 {
public static void main(String[] args) {
//操作比较大的数的时候,注意溢出问题
//JDK7新特性:数字之间可以使用下划线分割
int money = 10_0000_0000;
System.out.println(money);//1000000000 并不会输出_
int year = 20;
int total = money*year;
System.out.println(total);//-1474836480 溢出
long total2 = money*year;
System.out.println(total2);//-1474836480 溢出(易错点:此时,计算结果为int类型,然后转换为long类型为时已晚)
long total3 = money*((long)year);
System.out.println(total3);//20000000000 数据类型不同,计算时,转换为其中较大的类型进行计算
//代表long类型的后缀使用大小写l L都可以,由于小写l容易看成数字1,通常用大写L
}
}
4. 变量、常量、作用域
视频讲解:变量、常量、作用域(狂神)
4.1 变量
变量是什么:就是可以变化的量
- Java是一种强类型语言,每个变量都必须声明其类型
- Java变量是程序中最基本的存储单元,其要素包括变量名、变量类型和作用域。
- 注意事项:
1.每个变量都有类型,类型可以是基本类型,也可以是引用类型。
2.变量名必须是合法的标识符。
3.变量声明是一条完整的语句,因此每一个声明都必须以分号结束。
示例1:
public class Demo07 {
public static void main(String[] args) {
int a=1,b=2,c=3;//不提倡,程序可读性很低。通常每行定义一个变量。
String name = "zach";
char z = 'z';
double pi = 3.14;
}
}
示例2:
public class Demo08 {
//类变量(静态变量) static
static double salary = 10000;
//属性:变量
//实例变量:从属于对象;
// 如果没有进行初始化,这个类型的默认值是:
// 数值类型0 或 0.0 字符类型0 布尔值类型false
// 除了基本类型,其他(例如String类型)都是null。
String name;
int age;
//main方法
public static void main(String[] args) {
//局部变量:必须声明和初始化值
int i;
i = 10;
System.out.println(i);
//System.out.println(age);//java: 无法从静态上下文中引用非静态 变量 age
//变量类型 变量名字 = new Demo08();
Demo08 demo08 = new Demo08();
System.out.println(demo08.age);//0
//类变量(静态变量) static
System.out.println(salary);//10000.0
}
//其他方法
public void add(){
}
}
4.2 常量
- 常量(Constant):初始化(initialize)后不能再改变的值!不会变动的值。
- 所谓常量可以理解成一种特殊的变量,它的值被设定后,在程序运行过程中不允许被改变。
- 常量名一般使用大写字符。
示例1:
public class Demo09 {
//修饰符static、final不分先后顺序。
static final double PI = 3.14;
public static void main(String[] args) {
System.out.println(PI);//3.14
}
}
★变量的命名规范:
- 所有变量、方法。类名:见名知意
- 类成员变量:首字母小写和驼峰原则:例如,monthSalary
- 局部变量:首字母小写和驼峰原则
- 常量:大写字母和下划线组成:MAX_VALUE
- 类名:首字母大写和驼峰原则:例如,Demo09,GoodMan
- 方法名:首字母小写和驼峰原则:例如,run(),runRun()
4.3 作用域
变量的作用域
- 类变量
- 实例变量
- 局部变量
具体参考 → 4.1 变量的示例2