入门"/>
Java快速入门
Java学习–程序基础
一、变量和数据类型
一、基本数据类型
基本数据类型是CPU可以直接进行运算的类型。Java定义了一下几种基本数据类型:
- 整数类型:
byte, short, int, long
- 浮点数类型:
float, double
- 布尔类型:
boolean
- 字符类型:
char
计算机内存的最小存储单元是字节(byte),一个字节就是一个8为的二进制数,即8个bit。
它的二进制表示范围从00000000
~11111111
,换算为十进制是 0255,十六进制是`00`ff
1.1、整型
各种整型能表示的最大范围如下:
byte
:-128 ~ 127short
:-32768 ~ 32767int
:-2147483648 ~ 2147483647long
:-9223372036854775808 ~ 9223372036854775807
public class IntEm{public static void main(String[] args) {int num1 = 2147483647;int num2 = -2147483648;int num3 = 2_000_000_000; // 加下划线更容易识别int num4 = 0xff0000; // 十六进制表示的16711680int num5 = 0b1000000000; // 二进制表示的512long long1 = 9000000000000000000L; // long型的结尾需要加LSystem.out.print(num1 + "\n" + num2 + "\n" + num3 + "\n" +num4 + "\n" +num5 + "\n" +long1);}
}
1.2、浮点型
浮点型的数就是小数,因为小数用科学计数法表示时,小数点可以浮动
public class FloatEm {public static void main(String[] args) {float f1 = 3.14f; float f2 = 3.14e38f; //科学计数法 3.14 * 10^38double d1 = 1.79e308;double d2 = -1.79e308;double d3 = 4.9e-324; //4.9 * 10^ - 324}
}
float 浮点型
后方续加上f
后缀
1.3、布尔型
public class BooleanEm {public static void main(String[] args) {boolean b1 = true;boolean b2 = false;boolean b3 = 5 > 3;int age = 18;boolean b4 = age >= 18;}
}
1.4、字符类型
public class CharEm{public static void main(String[] args) {char c1 = 'a';char c2 = '嘿';System.out.println(c1 + "\n" +c2 );}
}
注意:
char 字符型
使用单引号''
,且仅有一个字符,要和双引号""
的String 字符串类型
作区分
1.5、引用类型
除了上述数据类型外,其余的都是引用类型。如最常见的字符串类型 String
public class StringEm{public static void main(String[] args) {String s1 = "哈哈哈";}
}
1.6、常量
定义变量的时候,使用final
修饰符,使这个变量成为常量
public class FinalEm{public static void main(String[] args) {final double PI = 3.14; PI = 300; //error}
}
常量的变量名需全部
大写
,且不能再次赋值
,否则会报错
1.7、var关键字
使用var
关键字,减少变量类型书写,
编译器会根据赋值语句自动推断出变量的类型
public class VarEm{public static void main(String[] args) {var str = "玛卡巴卡";var myNum1 = 100;var myPi = 3.14;System.out.println(str + "\n" +myNum1 + "\n" +myPi);}
}
1.8、变量作用范围
可简单理解为变量的作用域
二、整数运算
2.1、四则运算
+
:加-
:减*
:乘/
:除%
:求余
int x = 12345 / 67;
//194
整数的数值是精确的,而且整数运算永远是精确的;
即使是除法也是精确的,因为两个整数相除只能得到结果的整数部分
int y = 12345 % 67;
// 17
特别注意
:整数的除数为0时运行将报错,但是编译不会报错
2.2、溢出
特别注意
:由于整数存在范围限制,如果计算结果超出了范围,就会产生溢出、但是溢出不会报错
,会返回一个奇怪的结果。
//溢出演示
public class OverEm {public static void main(String[] args){int x = 2147483640;int y = 15;System.out.println(x + y);//-2147483641}
}
若想解决,可将 int 类型改为 long 型
2.3、自增/自减
++
:自增--
:自减
int x = 100;
x++;
x--;
++x;
--x;
简写运算符+=
,-=
,*=
,/=
int x = 100;
x += 1; // x = x + 1
2.4、移位运算
在计算机中,整数总数以二进制的形式表示。
如int
类型的整数7
使用二进制表示为111
使用4字节的二进制表示如下:
00000000 0000000 0000000 00000111
可以对整数进行移位运算。将整数7
左移一位得到整数14
,左移两位将是整数28
int n = 7; // 00000000 00000000 00000000 00000111 = 7
int a = n << 1; // 00000000 00000000 00000000 00001110 = 14
int b = n << 2; // 00000000 00000000 00000000 00011100 = 28
int c = n << 28; // 01110000 00000000 00000000 00000000 = 1879048192
int d = n << 29; // 11100000 00000000 00000000 00000000 = -536870912
左移29位时,由于最高位变成
1
,因此结果变成了负数。
如果对一个负数进行右移,最高位的1
不动,结果任然是一个负数
int n = -536870912;
int a = n >> 1; // 11110000 00000000 00000000 00000000 = -268435456
int b = n >> 2; // 11111000 00000000 00000000 00000000 = -134217728
int c = n >> 28; // 11111111 11111111 11111111 11111110 = -2
int d = n >> 29; // 11111111 11111111 11111111 11111111 = -1
无符号右移运算>>>
,特点是不管符号位,右移后高位总是补0
,因此对一个负数使用>>>
右移,它会变成整数,因为最高位的1
成了0
。
int n = -536870912;
int a = n >>> 1; // 01110000 00000000 00000000 00000000 = 1879048192
int b = n >>> 2; // 00111000 00000000 00000000 00000000 = 939524096
int c = n >>> 29; // 00000000 00000000 00000000 00000111 = 7
int d = n >>> 31; // 00000000 00000000 00000000 00000001 = 1
对byte
和short
类型进行移位时,会首先转换为int
再进行位移。
仔细观察可发现,左移实际上就是不断地×2,右移实际上就是不断地÷2。
2.5、位运算
位运算是按位进行与、或、非、异或
的运算
& 位与运算
:必须两个数同时为1
,结果才为1
n = 0 & 0; // 0
n = 0 & 1; // 0
n = 1 & 0; // 0
n = 1 & 1; // 1
| 位或运算
:或运算的规则是,只要任意一个为1
,结果就为1
n = 0 | 0; // 0
n = 0 | 1; // 1
n = 1 | 0; // 1
n = 1 | 1; // 1
~ 位非运算
:非运算的规则是,0
和1
互换
n = ~0; // 1
n = ~1; // 0
^ 位异或运算
:如果两个数不同,结果为1
,否则为0
n = 0 ^ 0; // 0
n = 0 ^ 1; // 1
n = 1 ^ 0; // 1
n = 1 ^ 1; // 0
public class Main {public static void main(String[] args) {int i = 167776589; // 00001010 00000000 00010001 01001101int n = 167776512; // 00001010 00000000 00010001 00000000System.out.println(i & n); // 167776512}
}//理解
167776589 // 00001010 00000000 00010001 01001101
167776512 // 00001010 00000000 00010001 00000000
167776512 // 00001010 00000000 00010001 00000000按照 位或 进行运算。
01001101 和 00000000 单个运算的结果均为 0 ,故结果也为 00000000
将两个操作位的数字转化为4字节二进制,将两个操作位的第n位根据运算表达式里的方法进行
与、或、非、异或
运算,并将运算的返回值给到结果对应的4字节二进制第n位上
2.6、运算优先级
Java的计算表达式中,运算优先级从高到低依次是:
()
!
~
++
--
*
/
%
+
-
<<
>>
>>>
&
|
+=
-=
*=
/=
2.7、类型自动提升与强制转型
在运算过程中,如果参与运算的两个数类型不一致,那结果将会为较大的整型
public class MyClass {public static void main(String[] args){short s = 1234;int i = 123456;int x = s + i; // s自动转型为intshort y = s + i; // 编译错误!}
}
可通过(类型)
强制转换,将大范围整数转换为小范围整数
int i = 12345;
short s = (short) i
注意:超出范围的强制转型会得到错误的结果,原因是转型时,
int
的两个高位字节直接被扔掉,仅保留了低位的两个字节
三、浮点数运算
3.1、计算误差
浮点数只能进行 加减乘除
计算
浮点数虽然表示范围特别大,但是常常无法进行精确表示
浮点数0.1
在计算机中无法进行精确表示,因为十进制的0.1换算成二进制是一个无限循环小数,无论使用float
还是double
,都只能存储一个0.1
的近似值。但是0.5
这个浮点数可以精确表示。
public static FloatMain{public static void main(String[] args) {double d1 = 1.0/10;double d2 = 1 - 9.0/10;System.out.println(x); // 0.1System.out.println(y); // 0.09999999999999998}
}
3.2、判断相等
由于浮点数计算存在误差,所以比较两个浮点数是否相等的正确比较方法是判断两个浮点数只差的绝对值是否小于一个很小的数:
//使用Math.abs()获取x,y之差的绝对值
double r = Math.abs(x - y);
//进行判断
if(r <0.000001) {//可认为相对
} else {//不等
}
3.3、溢出
整数运算在除数为0
时会报错,而浮点数不会报错,但会返回几个特殊值,
NaN
:表示非数字Infinity
:表示无穷大-Infinity
:表示负无穷大
3.4、类型提升
如果参与运算的两个数其中一个是整型,那么整型可以自动提升到浮点型
public class Main {public static void main(String[] args) {double d = 1.2 + 24.0/5;System.out.println(d); // 6.0}
}
注意:在一个复杂的四则运算中,两个整数的运算不会出现自动提升的情况
double d = 1.2 + 24/5;
System.out.println(d); // 5.2
24/5
这个表达式会按照整型进行计算,结果为4
3.5、强制转型
可以将浮点数强制转型为整数。但转型时,浮点数的小数部分会被丢掉,如果转型后超过了整型能表示的最大范围,将返回整型的最大值
int n1 = (int) 12.3; //12
int n2 = (int) 12.7; //12
int n3 = (int) -12.7; //-12
int n4 = (int) (12.7 + 0.5); // 13
int n5 = (int) 1.2e20; //2147483647
使用强制转型进行四舍五入
double d = 2.6;
int n = (int) (d + 0.5) // 3
当d为负数时,将
0.5
改为-0.5
四、布尔运算
布尔类型boolean
,永远只有true
和false
两个值。
布尔运算是一种关系运算,包括一下几类:
- 比较运算符:
>
,>=
,==
,<
,<=
,!=
- 与运算:
&&
- 或运算:
||
- 非运算:
!
运算符优先级为
!
>
,>=
,<
,<=
==
,!=
&&
||
4.1、短路运算
在与运算&&
中,使其中一项始终为false
,这样条件将永远不会满足
4.2、三元运算符
三元运算符:b?x:y
和Js中的使用方法一致
五、字符和字符串
5.1、字符类型
字符类型char
是基本数据类型,是character
的缩写。一个char
只保存一个
Unicode字符,并且字符放在''
中。
char w = 'S';
char c = '中';
因为Java在内存中总是使用Unicode表示字符,所以,一个英文字符和一个中文字符都用一个char
类型表示,他们都占用两个字节。要显示一个字符的u你从i的编码,只需将char
类型直接赋值给int
类型即可
int n1 = 'A'; //字母“A”的Unicodde编码是65
int n2 = '中'; //汉字“中”的Unicode编码是20013
还可以直接用转义字符\n
+Unicode编码来表示一个字符:
// 注意是十六进制:
char c3 = '\u0041'; // 'A',因为十六进制0041 = 十进制65
char c4 = '\u4e2d'; // '中',因为十六进制4e2d = 十进制20013
5.2、字符串类型
字符串类型String
是引用类型,我们用双引号""
表示字符串。一个字符串可存储0到任意个字符。
String s = "";
String s1 = "ads";
String s2 = "哇哈哈";
如果字符串中包含""
,则需要使用转义字符\
String s = "abc\"xyz"; // 表示:abc"xyz
因为\
是转义字符,所以\\
表示一个\
字符
String s = "abc\\xyz"; //表示:abc\xyz
常见的转义字符包括:
\"
表示字符"
\'
表示字符'
\\
表示字符\
\n
表示换行符\r
表示回车符\t
表示Tab\u####
表示一个Unicode编码的字符
5.3、字符串连接
使用+
对字符串进行连接
public class Main {public static void main(String[] args) {int age = 25;String s = "age is " + age; System.out.println(s); // age is 25}
}
5.4、多行字符串
传统使用+
和\n
拼接多行字符串
String s = "first line \n"+ "second line \n"+ "end";
从Java13开始,字符串可以使用"""..."""
表示多行字符串了
public class Main {public static void main(String[] args) {String s = """SELECT * FROMusersWHERE id > 100ORDER BY name DESC""";System.out.println(s);//SELECT * FROM// users//WHERE id > 100//ORDER BY name DESC////注意:上面一行空白是由于结尾处的"""前方有换行导致的,//下方为消除空行的写法String s2 = """SELECT * FROMusersWHERE id > 100ORDER BY name DESC""";System.out.println(s2);//SELECT * FROM// users//WHERE id > 100//ORDER BY name DESC}
}
5.5、不可变特性
public class Main {public static void main(String[] args) {String s = "hello";System.out.println(s); // 显示 hellos = "world";System.out.println(s); // 显示 world}
}
字符串s
变了吗?其实变的不是字符串,而是变量s
的“指向”,
执行String s = "hello";
时,JVM虚拟机先创建字符串"hello"
,然后,把字符串变量s
指向它:
紧接着,执行s = "world";
时,JVM虚拟机先创建字符串"world"
,然后,把字符串变量s
指向它:
原来的字符串"hello"
还在,只是我们无法通过变量s
访问它而已。因此,字符串的不可变是指字符串内容不可变。
5.6、空值null
引用类型 的变量可以指向一个空值null
,他表示不存在,及该变量不指向任何对象
String s1 = null; // s1是null
String s2; // 没有赋初值值,s2也是null
String s3 = s1; // s3也是null
String s4 = ""; // s4指向空字符串,不是null
注意:需要区分空值
null
和空字符串""
,空字符串是一个有效的对象,他不等于null
练习:将int值视为字符Unicode编码,然后将他们进行拼接
int aa = 72;
int bb = 105;
int cc = 65281;
// FIXME:
// 使用 (char) 将int 类型转为对应的 char 类型
// 在最前方添加"",表明拼接后为字符串类型
String s =""+(char)aa+ (char)bb + (char)cc;
System.out.println(s);
六、数组类型
6.1、定义数组
public class Main {public static void main(String[] args) {//创建一个长度为5的 int 数组int[] myArr = new int[5];myArr[1] = 1;myArr[2] = 2;myArr[3] = 3;myArr[4] = 4;myArr[5] = 5;}
}
定义一个数组类型的变量,使用数组类型类型[]
,例如:int[]
、float[]
。和单个单位类型变量不同,数字变量初始化必须使用 new int[]
表示创建以容
Java的数组有几个特点:
- 数组所有元素初始化为默认值,整型都是
0
,浮点型是0.0
,布尔型是false
; - 数组一旦创建后,大小就不可改变。
使用数组变量.length[]
获取数组大小
数组是引用类型,在使用索引访问元素时,如果索引超出范围,运行时将报错
可以在定义数组时直接指定初始化的元素,这样就不必写出数组大小,而是由编译器自动推断数组大小。
public class Main {public static void main(String[] args) {int[] myArr = new int[] {1,2,3,4,5}//可进一步简写为下面这样int[] myArr2 = {1,2,3,4,5}}
}
6.2、理解
数组大小不可改变
public class Main {public static void main(String[] args) {// 5位同学的成绩:int[] ns;ns = new int[] { 68, 79, 91, 85, 62 };System.out.println(ns.length); // 5ns = new int[] { 1, 2, 3 };System.out.println(ns.length); // 3}
}
数组大小变了吗?看上去好像是变了,但其实根本没变。
对于数组ns
来说,执行ns = new int[] { 68, 79, 91, 85, 62 };
时,它指向一个5个元素的数组:
ns│▼
┌───┬───┬───┬───┬───┬───┬───┐
│ │68 │79 │91 │85 │62 │ │
└───┴───┴───┴───┴───┴───┴───┘
执行ns = new int[] { 1, 2, 3 };
时,它指向一个新的3个元素的数组:
ns ──────────────────────┐│▼
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ │68 │79 │91 │85 │62 │ │ 1 │ 2 │ 3 │ │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
但是,原有的5个元素的数组并没有改变,只是无法通过变量ns
引用到它们而已。
6.3、字符串数组
String[] names = {"ABC", "XYZ", "zoo"};
数组元素可以是值类型(如int)或引用类型(如String),但数组本身是引用类型;
更多推荐
Java快速入门
发布评论