java基础-基本语法
java的命名规则
- 1、java中定义类名时,在实际工作中要求类名必须以大写字母开头,后者可以跟字母和数字的任意组合。(用小写字母或下划线或$或汉字开头也不会错,这里必须这是人为规定的,并不代表会报错或运行异常,变量方法也是,都是为了方便其他都不提倡,变量名,方法名也一样都是最提倡的做法)
- 2、java中变量名必须是一个以字母开头的由字母和数字构成的序列。
- 3、java对大小写敏感,书写时一定要注意区分大小写。如果出现大小写拼写错误(如将main写成Main),那么程序将无法运行。
- 4、java中方法名首字母小写,第二个单词开始大写且为动词。
- 5、常量名习惯使用大写,单词之间用下划线连接。
注释
在java中有三种写注释的方式:
- 行注释:
//,其注释内容从//开始到本行末结束。
- 块注释:
/**/当需要长篇的注释时,可以使用将一段比较长的注释括起来。多行注释不能嵌套使用。
- 文档注释:
/**使用结束,可以用来自动生成文档。
*
*/
注释不会出现在字节码文件中,即注释不会影响到字节码文件的大小,Java编译器编译时也会跳过注释语句。
java语言有哪些词法符号?分隔符和空白符号的区别是什么
在词法分析阶段,源代码被分解为词法符号、空白符、和注释。最终词法分析从源程序中去掉空白符号和注释,产生词法符号流。词法符号流是进一步进行词法分析的基础。词法符号有5中:关键字、标识符、文字、运算符、分隔符。
空白符主要用来分割相邻的词法符号,但其本身并不是词法符号。分隔符是一种词法符号,它除了能够分割其他词法符号以外,还有特定的语法作用和规则。
java标识符
由数字,字母和下划线(_),美元符号($)或者人民币符号“¥”组成。首字母不能是数字,在Java中是区分大小写的,而且还要求首位不能是数字。关键字不能当作标识符。驼峰式命名规则,从第二个单词开始,每个单词的首字母要大写。
注意:Java不采用通常语言使用的ASCII字符集,而是采用unicode这样的标准的国际字符集,所以这里的字母的含义:英文、汉字等等,但尽量不要用汉字来定义标识符,更不能用关键字来作为变量名和方法名,但可以是关键字与其他单词的组合形式。
代码规范
花括号应成对出现,第一个花括号应在第一行语句后面
方法后面紧跟花括号,没有空格(没有那么严格)
关键字(while、for、if)后面应留一个空格
for(int i=0; i<10; i++);即符号两边无空格,;后面有空格
int i = 10;即=两边有空格
if(i>10);符号两边无空格
if(i>10 && i<40);中间符号两边有空格
代码折行应按照代码等级对齐,运算符写在下一行
关键字
关键字:其实就是某种语言赋予了特殊含义的单词。java中关键字都是有小写字母组成
保留字:其实就是还没有赋予特殊含义,但是准备日后要使用过的单词。
java中把true、false、null作为常量对待,并不在关键字中,有些教材作为关键字对待也是可以的
常量和变量
常量:是在程序中的不会变化的数据。习惯上,常量名使用大写(小写不报错)。若是两个单词以上组成用"_"连接。
变量:其实就是内存中的一个存储空间,用于存储常量数据。(作用:方便于运算。因为有些数据不确定。所以确定该数据的名词和存储空间。特点:变量空间可以重复使用。)
什么时候定义变量?
只要是数据不确定的时候,就定义变量。
变量的类型
成员变量,局部变量,类变量,实例变量
1、方法外但在类声明定义的变量为成员变量,作用域是整个类,在方法中定义的变量为局部变量,作用域为定义的方法体中。
2、类变量是用static声明的成员变量,没有声明的为实例变量,实例变量存放在堆内存中,类变量放在方法区中,类变量也可以被对象调用,而实例变量不能用类名调用。
3、局部变量在方法调用时创建,方法执行完撤销;实例变量创建类实例时创建,实例撤销时撤销;类变量在类加载时创建,类撤销时撤销。循环语句中的定义的变量循环一次,重新定义一次所以不会有重复定义的错误。如for语句中有int a = 10;不会有错。
4、变量调用前必须初始化完成,局部变量必须显示的初始化,成员变量会分配默认值,char初始值是16位的0;
变量的声明和赋值
赋给变量一个字符串,实际上变量存储的是字符串对象的首地址,输出的时候自动调用toString方法
声明变量可以一次声明多个,如:int x,y;
可以边声明边赋值:int s = 5; int i= 5, j = 6; int x,y = 8;
可以先声明后赋值:int x; x=5;(在方法中可以或在类中用{}括起来赋值语句的代码块)
可以赋多值:x=y=5;
对成员变量的操作(赋值,运算等)必须放在方法中或代码块中,否则语法错误,如:成员变量可以声明时赋初值但不能声明后在类中赋值。
实例成员变量会被赋默认值,final的实例成员变量不会被赋默认值
变量空间的开辟需要什么要素呢?
数据类型。变量名称。变量的初始化值。
变量的作用域和生存期:
变量的作用域:作用域从变量定义的位置开始,到该变量所在的那对大括号结束;
生命周期:变量从定义的位置开始就在内存中活了;变量到达它所在的作用域的时候就在内存中消失了;
生存周期:静态变量由类来决定,成员变量由对象来决定,局部变量用{}来界定。
变量的数据类型
8个基本数据类型:
byte、short、int、long、float、double、char、boolean
- 基本数据类型:它们存储的都是数据量比较小的数据,只需要1个或几个字节就可以了,因此,这些数据类型的变量的二进制值就直接保存着它们的值。
基本数据类型取值范围:
- byte一个字节
- char(两个字节无符号unicode编码0—2^16-1),
- short两个字节带符号(-2^15—2^15-1),
- int四个字节(-2^31 — 2^31-1),
- float四个字节,
- long,double八个字节,
- boolean(存储大小跟虚拟机有关,java中整型值和布尔值之间不能进相互转换)
取值范围计算方法
以int为例:
占用4个字节,4x8=32位;
最高位为符号位,最大值就是011111共31个1,也就是2^31-1;
最小值就是100000共31个0,也就是2^31加个负号。
类型转换
级别从低到高为:byte,char,short(这三个平级)-->int-->float-->long-->double
自动类型转换:从低级别到高级别,系统自动转的;因为是高位扩展不存在转换风险
强制类型转换:什么情况下使用?把一个高级别的数赋给一个别该数的级别低的变量;
+=这样的运算包含了一个隐含的强转转换。要舍弃高位存在风险
byte b = 3; b = (byte)(b*3); b*3自动转换成int型用(byte)强制向高级转换。
long a = 6; 6为int型自动转换成long型
int smallval = 99L; 99L是long型,非法
double z = 12.1f; float型自动转换成double型
float z1 = 12.414;12.414是double型,非法
int a; double b = 3.14; a = (int)b; 将b值转换成int型,b的值仍然是3.14 double型
浮点型强转其他类型,都是先舍弃小数,转换为int型再转为其他类型,如果的得到的整数大于int类型的最大值,就会赋于其int类型的最大值,再进行转换
char b = 97;得到b值为a用的是ASCII值
int b = 'a';得到b值为97
'a'+1的值是98
如果低级类型为char型,向高级类型(整型)转换时,会转换为对应ASCII码值,再做其它类型的自动转换。char转int可以自动也可以强制
char a = '\u0022';得到b值为",先转换ASCII码值再转换
int a = '\u0022';得到a值为34
任何数和字符串相加都结果都为字符串。
short s1 = 1; s1 = s1 + 1;编译器报错,s1+1值为int型,再给short型需显示转换
short s1 = 1; s1 += 1;可以正确编译,隐含有强制转换等价于:s1 = (short)(s1+1),
char a = '\u005'; a == 0x0005L;为true.双目算术也会转换
byte i = 1; i+1为int型,i++为byte型,true? 12:i;结果为byte型
3个引用数据类型:
数组、类、接口。(引用类型大小统一为4个字节,记录的是引用对象的地址)
null可以作为任何引用类型数据,如返回要Person类型返回null就不错。
- 引用数据类型:主要用来指向某个对象,对象保存的数据一般都比较大,如果在传递参数、赋值等工作的时候,每次都把数据完全拷贝一次会影响到效率,因此定义成一种引用类型,引用类型变量的值存放的是数据的地址。
- 对象一般是通过new语句创建出来的,它保存在堆空间中,可以被多个引用类型的变量所引用
后缀
long:数值以l或L结尾,
float:数值以f或F结尾,
double:数值以d或D结尾或为浮点数值时不加。
字面量
整型字面量常量是32位的int型
默认的浮点字面量常量是64位的double型,但像byte b=1;float f=1.0;当一个字面量的值被赋给一个byte 或short型的变量时,如果字面量的值没有超过对应类型的范围时不会产生错误。
浮点型运算的弊端
浮点型的数据直接用运算符进行运算会损失精度,可以:
BigDecimal a=new BigDecimal(1.0);
或者BigDecimal a=BigDecimal.valueOf(1.0);
BigDecimal b=new BigDecimal(2.7);
a=a.add(b);
System.out.println(a.doubleValue())//不加doubleValue()方法还不能精确
减法用a=a.subtract(b),乘法用a=a.multiply(b),除法用a=a.divide(b, 2,BigDecimal.ROUND_HALF_UP);2表示精确的位数,能除尽a=a.divide(b)也行
boolean类型数据
c/c++中会有0代表false,非0代表true,这样可以让程序带来高效,但也带来一定的危险性。
java出于安全考虑,限制了这样的做法,只能用true和false来代表真假。
boolean和Boolean比较
boolean是基本数据类型,Boolean是类。
boolean有true和false两种值,Boolean除了true和false还有null
java5.0.之前,不能把Boolean用于条件语句,需要转换为boolean以后再使用。
char数据类型
java中的char采用的Unicode编码格式,2个字节表示一个字符
尽管char可以表示的数值有那么多,但事实上并非每个数值都对应一个字符
char可以和int,short,long整型进行类型转换,是因为它们本质上都是以二进制整型的形式进行存储的。
转义字符
一些特殊的字符不能用一个特定的数字、字母或符号表示、例如:换行符、制表符、双引号等,为了表示这些特殊的字符,需要引入转义字符的概念。
所有的计算机语言都无法回避转义字符的概念,它们都统一用反斜杠来表示转义。
使用”\”来代表转义,它与紧跟它后面的字符组成转义字符,达到转义目的。
表2-3 Java中常用的转义字符
|
转义序列 |
字符名称 |
Unicode 编码 |
|
\' |
单引号 |
0x0027 |
|
\" |
双引号 |
0x0022 |
|
\\ |
反斜杠 |
0x005C |
|
\0 |
空 |
0x0000 |
|
\a |
警报 |
0x0007 |
|
\b |
退格符 |
0x0008 |
|
\f |
换页符 |
0x000C |
|
\n |
换行符 |
0x000A |
|
\r |
回车 |
0x000D |
|
\t |
水平制表符 |
0x0009 |
|
\v |
垂直制表符 |
|
java中的转义字符应用比较广泛,例如表示Windows操作系统下的文件路径时,就要用到转义
String path=”c:\\windows\\hello”;
运算符
/符号:只有当参与/运算的两个操作数都是整数时,表示整数除法;否则,表示浮点除法。如:15/2为7,15.0/2为7.5。
%符号:两边可以是浮点型,结果为浮点型,有负数时结果符号取决于符号左边
+符号:可以作字符串的连接运算,如:“,”+2
(8+i++)……:先计算8+i之后马上i+1之后算括号外面
三元运算符:是if……else的简写形式,判断?a:b;
&&、||:表示短路的逻辑运算,符号右边是否执行看情况,做逻辑与/或运算
&、|:表示非短路运算,大多数时使用短路运算。符号右边都会执行,做逻辑与/或运算和位与/或运算
&:任何数与1&,其结果等于自身,任何数与0&,其结果都等于0
|:任何数与0|,其结果等于自身,任何数与1|,结果等于1
^: 任何数与一个指定的数异或两次,其结果为自身,a^b与b^a值是相等的
移位运算符:
移位运算符只能作用在整型数据上,<<左移,砍掉高位,低位补0
>>右移,砍掉低位,高位要看最高位符号位,符号位为1就补1,符号位为0就补0
>>>无符号右移,砍掉低位,不考虑符号,高位都补0
位移运算时,首先会将移动的位数对该类型占的位数进行取余,例如 a>>33 相当于 a>>1
二、八、十六进制
十进制转其他进制:
除进制,取余,直到商为0,将余数反转,实现方式: 循环、递归
其他进制转十进制:
用乘法,第n位的数*进制的n次方,结果全部相加,n从0开始
二进制转其他进制
二进制转八进制每三位一看
二进制转十六进制每四位一看,除16取余、也可以用位移的方式实现,超过9的数需要用字母来替代, 3种方式:通过条件判断、定义数组查表法、Character.forDigit
原码,反码,补码
原码:在数值前直接加一符号位的表示法。
例如: 符号位 数值位
[+7]原= 0 0000111 B [-7]原= 1 0000111 B
数0的原码有两种形式 [+0]原=00000000B [-0]原=10000000B
-0的补码表示了-128
反码:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。
原码10010= 反码11101 (10010,1为符号码,故为负),反码加1时符号位不参与运算
补码:正数的补码与其原码相同;负数的补码是在其反码的末位加1。
与原码、反码不同,数值0的补码只有一个,即 [0]补=00000000B。
- 计算机的运算规则, 都是二进制数的累加
- 负数如何表示? 原码--取反-->反码--加1-->补码 ,即负数是以其补码表示的
- 11111111为-1,10000000为-2^7
- 运算时用的是补码进行运算,符号位参与运算,所得结果仍为补码
- 计算机中的数据都是以补码存放的
- 所用的数据在计算机中存储都是以二进制形式,数据都会先转成数字类型,再转换成二进制
码表
每个字符都对应键盘上的一个键,只有enter键对应两个字符(\r\n),每个字符占1个字节。允许128个字符,是unicode编码前128个字符
ASCII码
|
ASCII 码 |
字符 |
|
ASCII 码 |
字符 |
|
ASCII 码 |
字符 |
|
ASCII 码 |
字符 |
||||
|
十进位 |
十六进位 |
|
十进位 |
十六进位 |
|
十进位 |
十六进位 |
|
十进位 |
十六进位 |
||||
|
032 |
20 |
|
|
056 |
38 |
8 |
|
080 |
50 |
P |
|
104 |
68 |
h |
|
033 |
21 |
! |
|
057 |
39 |
9 |
|
081 |
51 |
Q |
|
105 |
69 |
i |
|
034 |
22 |
" |
|
058 |
3A |
: |
|
082 |
52 |
R |
|
106 |
6A |
j |
|
035 |
23 |
# |
|
059 |
3B |
; |
|
083 |
53 |
S |
|
107 |
6B |
k |
|
036 |
24 |
$ |
|
060 |
3C |
< |
|
084 |
54 |
T |
|
108 |
6C |
l |
|
037 |
25 |
% |
|
061 |
3D |
= |
|
085 |
55 |
U |
|
109 |
6D |
m |
|
038 |
26 |
& |
|
062 |
3E |
> |
|
086 |
56 |
V |
|
110 |
6E |
n |
|
039 |
27 |
' |
|
063 |
3F |
? |
|
087 |
57 |
W |
|
111 |
6F |
o |
|
040 |
28 |
( |
|
064 |
40 |
@ |
|
088 |
58 |
X |
|
112 |
70 |
p |
|
041 |
29 |
) |
|
065 |
41 |
A |
|
089 |
59 |
Y |
|
113 |
71 |
q |
|
042 |
2A |
* |
|
066 |
42 |
B |
|
090 |
5A |
Z |
|
114 |
72 |
r |
|
043 |
2B |
+ |
|
067 |
43 |
C |
|
091 |
5B |
[ |
|
115 |
73 |
s |
|
044 |
2C |
, |
|
068 |
44 |
D |
|
092 |
5C |
\ |
|
116 |
74 |
t |
|
045 |
2D |
- |
|
069 |
45 |
E |
|
093 |
5D |
] |
|
117 |
75 |
u |
|
046 |
2E |
. |
|
070 |
46 |
F |
|
094 |
5E |
^ |
|
118 |
76 |
v |
|
047 |
2F |
/ |
|
071 |
47 |
G |
|
095 |
5F |
_ |
|
119 |
77 |
w |
|
048 |
30 |
0 |
|
072 |
48 |
H |
|
096 |
60 |
` |
|
120 |
78 |
x |
|
049 |
31 |
1 |
|
073 |
49 |
I |
|
097 |
61 |
a |
|
121 |
79 |
y |
|
050 |
32 |
2 |
|
074 |
4A |
J |
|
098 |
62 |
b |
|
122 |
7A |
z |
|
051 |
33 |
3 |
|
075 |
4B |
K |
|
099 |
63 |
c |
|
123 |
7B |
{ |
|
052 |
34 |
4 |
|
076 |
4C |
L |
|
100 |
64 |
d |
|
124 |
7C |
| |
|
053 |
35 |
5 |
|
077 |
4D |
M |
|
101 |
65 |
e |
|
125 |
7D |
} |
|
054 |
36 |
6 |
|
078 |
4E |
N |
|
102 |
66 |
f |
|
126 |
7E |
~ |
|
055 |
37 |
7 |
|
079 |
4F |
O |
|
103 |
67 |
g |
|
127 |
7F |
DEL |
gb2312码表:
英文占1个字节(正数),汉字占两个字节(负数),完全兼容ASCII码表,没有特征码
gbk码表:
英文占1个字节(正数),汉字占两个字节(第一个是负数,第二个可正可负),没有特征码
unicode码表:
国际码表,收罗了世界上大部分常用文字,所有字符都占两个字节,文件前多出的两个字节为特征码来识别是unicode编码的,java用的Unicode编码
UTF-8码表:
每个字符占1~3个字节,英文占1个,汉字占3个,前三个为特征码
java编译成class文件用的Unicode编码
方法
- java语言中以方法来表示函数
- 调用方法时实参传值给形参,形参为局部变量,它的值的改变不影响实参。
2、方法的重载:同名,分辨根据形参的类型和个数,跟方法的返回类型无关
3、静态的方法调用的方法要为静态,否则用对象调用,(静态的方法/变量/代码块在类加载时初始化,没加载当然不能用)
4、main方法必须为静态
5、方法遇到return语句时就会马上调用结束,return后面不能用{ };会报错,return语句会用到箱子作为各方法传递参数的媒介,如return num++;先把num值装箱后num++,传递箱子,return结束方法,形参num销毁
6、如果方法的返回值类型为void,此时,不能使用return返回一个值,但是可以使用return语句结束方法调用
7、为了提高代码的复用性,可以将其定义成一个单独的功能,该功能的体现就是java中的方法。
8、方法中只能调用方法,不能定义方法。
9、主方法的存在,仅为该类是否需要独立运行,如果不需要,主方法是不用定义的。
- 形参和实参:实参的值拷贝一份给形参,1java方法基本数据类型是传值,对象类型传引用。(java只有传值这种参数传递方式,而引用类型变量的值就是引用,简言之还是传值)
2当参数是对象时,无论方法体内进行了何种操作,都不会改变实参对象的引用。
3当参数是对象时,只有在方法内部改变了对象的内容时,才会改变实参对象内容。
(由于对象地址作为形参相当于拷贝不影响实参指向地址,但形参指向的地址所存的内 容代表同一块地方,值改变就都改变了,即对象地址不变值可能改变)
13各方法的相互调用过程为,压栈,出栈,弹栈的过程(如装子弹的梭子),刚被调用的方法压栈前一个调用的方法(前一个方法调用到当前准备执行的方法),这个方法执行就是出栈,前一个方法弹栈准备执行,
修饰符
1当重写父类成员方法时,子类的成员方法不能比父类的成员方法权限小,一般重写把权限定义相同即可。构造方法不能被重写,可以被重载。
2局部变量前不能放置任何访问修饰符,非访问只能放final或什么都不加
有多个修饰符组合使用时没有顺序要求。如:final static public int a(){……}
修饰符分类
java的修饰符有:权限修饰符:public、protected、friendly、private
修饰符:abstract、static、final
权限(访问)修饰符
public、protected、friendly、private
public 使用对象:类、接口、变量、方法
protected使用对象:变量、方法 注意:不能修饰类(外部类)
friendly 使用对象:类、接口、变量、方法。(即缺省,什么也不写)
private 使用对象:变量、方法 注意:不能修饰类(外部类)
修饰符
abstract使用对象:类、接口、方法
static 使用对象:类、变量、方法、初始化方法(注意:修饰类时只能修饰 内部类 )
final 使用对象:类、变量、方法
transient:告诉编译器,在类对象序列化的时候,此变量不需要持久保存
volatile:指出可能有多个线程修改此变量,要求编译器优化以保证对此变量的修改能够被正确的处理
native:用该修饰符定义的方法在类中没有实现,而大多数情况下该方法的实现是用C、C++编写的。
synchronized:修饰方法,多线程的支持
jdk1.8定义了default修饰符可以修饰接口里面的方法,这个方法可以定义实现,表示这个方法的默认实现,这个接口的实现类实现了这个接口之后,不用管这个default修饰的方法,也可以直接调用
外部类修饰符
外部类是相对于内部类而言的,内部类是定义在类里面的类。
类的修饰符
访问修饰符 非访问修饰符 class……
- 访问修饰符:
public(可以被所有类访问使用)
friendly(默认的,可以被同包中的类访问使用)
- 非访问修饰符:
final(表示类不能被继承)
abstract(表示抽象类,由子类实现方法)
接口修饰符
权限修饰符
public:所有包可见
friendly:(缺省)同一个包中可见
内部类修饰符
内部类又分:成员内部类、局部内部类、静态内部类、匿名内部类
成员内部类:作为外部类的一个成员存在,与外部类的属性、方法并列
局部内部类:定义在外部类的方法体里面的类
静态内部类:使用static修饰的内部类
匿名内部类:就是没有名字的内部类
成员内部类
访问修饰符:
public:
protected:
private:private不能修饰外部类
非访问修饰符:
abstract:
final:
static:可以当做普通类使用,而不用先实例化一个外部类。(用他修饰后,就成了静态内部类了)
局部内部类:
局部类有一个优势,即对外部世界完全隐藏。即使是同一个类中其他的方法也不能访问它。
局部类可以访问包含它的外部类,同时也可以访问局部变量
局部类不能用public或private访问说明符进行声明,他的作用域被限定在这个方法中,
访问权限符与继承:
这里的访问权限修饰符指的是:修饰成员变量和方法。分两种情况:
1.子类与父类在同一个包中:
此时只有private修饰的变量和方法不能被访问。
2.子类与父类不在同一个包中:
此时private和friendly均不能被访问,protected和public可以
变量的修饰符
方法中的变量不能够有访问修饰符
访问修饰符 非访问修饰符 数据类型 变量名
访问修饰符:
|
访问权限 |
本类 |
同包 |
子类 |
其他包 |
|
public |
∨ |
∨ |
∨ |
∨ |
|
protected |
∨ |
∨ |
∨ |
× |
|
friendly |
∨ |
∨ |
× |
× |
|
private |
∨ |
× |
× |
× |
非访问修饰符:static 静态变量(类的实例都可访问,不创建实例就可访问用类名.变量名,每一次的调用修改都会被保留)
final 常量(值分配一次,不可修改)
transient暂时性域修饰符(实现不同对象的存档功能)
volatile 易失 ( 共享 ) 域修饰符 (成员变量可能被几个线程所控制和修改)
接口的变量总是需要定义成:public static final 类型 名称,但可以不用写的这么复杂,默认就是public static final
方法的修饰符
访问修饰符 修饰符 返回类型 方法名称(参数列表) throws 异常
访问修饰符:public protected friendly private
非访问修饰符
abstract:抽象方法(没有方法体)不能和private一起用,就是用来让子类继承或实现的
static: 静态方法 (属于整个类的类方法可用类名.方法名(参数)调用;而不使用 static 修饰、限定的方法是属于某个具体类对象的方法。只能引用静态变量或方法,也可创建出对象引用非静态变量方法;静态方法中不能用this,super关键字,因为对象有可能没创建呢,main方法中也不行,但main方法中可以用对象.的方式调用非静态成员属性或方法,静态成员方法中不可以。
静态方法的用途:
1.工具类中的方法都是static的
2.静态方法用于生产对象
)
final 最终方法 (功能和内部语句不能更改的方法,即最终方法不能重写可以重载和继承)
native 本地方法 (用其它的高级语言书写程序的方法体来提高程序运行速度)
synchronized 同步方法 (用于多线程共存的程序中的协调和同步。)
default jdk8之后接口中的方法可以用default修饰表示默认实现
接口方法说明:
可以使用的修饰符有public abstract default
方法默认的修饰符是:public abstract
jdk1.8后可以使用default进行修饰,表示该方法有默认实现,修饰的方法可以定义实现
这个接口的实现类实现了这个接口之后,不用管这个default修饰的方法,也可以直接调用
public interface NewCharacter {
public void test1();
public default void test2(){
System.out.println("我是新特性1");
}
}
final修饰符总结
final可以修饰局部变量,
final修饰的类:类不可以被继承
final修饰的变量:值分配一次,不可修改。
final修饰的变量是对象:也就是修饰的引用,引用的地址不可变,对象内部可以变。
final修饰的方法:最终方法不能重写可以重载和继承。
main()方法
main方法是java程序的入口方法
它是一个定义在类中的、公开的、静态的、无返回值的、参数为一个字符串数组的方法。
public static void main(String[] args){}
构造方法
- 构造方法名与所在类名一样
- 无返回值,也不能写void
- 默认的构造方法是无任何内容的空方法
- 构造方法只能通过new运算符调用,用户不能直接调用
- 可以被重载(一个类在定义时,如果没有定义过构造方法,那么该类中会自动生成一个空参数的构造方法,为了方便该类创建对象,完成初始化。如果在类中自定义了构造方法(不管有没有参数),那么默认的构造方法就没有了。
)如:
Test(){};
- 构造方法是在对象创建时,就被调用,用于初始化,而且初始化动作只执行一次。
可变参数
java在JDK1.5中首次推出java可变参数。
有的时候在设计方法时无法确定将来别人会传入的参数个数
底层其实是将这些元素进行数组的封装
可变参数只能被定义为方法的最后一个形参,否则编译会失败。
语法格式: 返回值 方法名(参数类型… 形参)如:run(String s1, String... str)
当与固定数参数冲突优先考虑固定个数
例如:
public void sm(String...strs){
for(String s:strs){
System.out.println("你的同学有"+s);
}
}
调用方法:
sm("张三","李四","王五","马六");
打印结果:

成员方法和成员变量
1、成员方法内不是成员变量的作用域,成员方法要访问成员变量要用this.(方法体中找不到变量,默认会自动加上this.所以不会报错超出作用域),即使成员方法中有相同的变量名用this.也会去访问成员变量,那个对象调用方法,this就代表那个对象。
2、方法中没有调用特有数据时就定义成静态
流程控制语句
顺序
分支:if条件语句,switch多选择语句
循环语句:
for循环语句,while循环,do while语句
for循环适合于能确定循环次数的循环结构
while语句适合单条件的的循环
do……while语句适合在执行某段代码之后再循环的时候。
while循环
while(循环条件){
循环操作
}
循环条件为true就进行循环操作,否则退出循环;
循环操作中有break退出循环;
循环操作中有return就结束循环所在的方法
do while循环
switch语句
switch(expression){
case value :
//语句
break; //可选
case value :
//语句
break; //可选
//你可以有任意数量的case语句
default : //可选
//语句
}
switch中的参数可以为int型要加上括号,但是byte、short、char类型的变量也可以给switch,原因是自动类型提升;String类型是java7开始支持。
当变量的值与 case 语句的值相等时,那么 case 语句之后的语句开始执行,直到 break 语句出现才会跳出 switch 语句。
default是没有相同值时执行,default可以写在switch结构中的任意位置;如果将default语句放在了第一行,则不管expression与case中的value是否匹配,程序会从default开始执行直到第一个break出现。
case后面可以不加括号
多个case可以写成一列共用执行语句如
switch(2){
case 1:
case 2:
case 3: return 20;break;
default:system.out.print("我就是传说中的你爸爸");
}
break语句和continue语句
break:不是跳出当前花括号,会跳出其所在的循环体结束循环。
continue直接反馈给循环体开始下一数。
break或continue语句单独存在时,下面不要定义其他语句,因为执行不到,编译会失败。
加标号:break3表示跳出标号3所对应的循环,continue3表示开始3下一次的循环
标号应该放在循环语句,switch语句或块语句前。否则不能被编译
带标号的循环语句:
outer: for(int i=0;i<5;i++){
for(int j=0;j<8;j++){
if(i==j) continue outer;//i=j的时候开始i的下一个值
System.out.print(“d”);
if(i==3) break outer;//i=3的时候循环结束
}
}
for循环,ForEach,迭代器
语法:
for循环:
for(int i=0;i<list.size();i++){}
foreach:
for (int i : list){}
Iterator:
Iterator<Long> iterator=l.iterator();
while(iterator.hasNext()){
Long next = iterator.next();
if(next.intValue()==1){
iterator.remove();
}
}
对比:
循环ArrayList时,普通for循环比foreach循环花费的时间要少一点;循环LinkList时,普通for循环比foreach循环花费的时间要多很多。
for循环通过下标的方式,对集合中指定位置进行操作
foreach:
是用Iterator但它不能像Iterator一样可以人为的控制,而且也不能调用iterator.remove();更不能使用下标来访问每个元素,所以不能用于增加,删除等复杂的操作。
需要循环数组结构的数据时,建议使用普通for循环,因为for循环采用下标访问,对于数组结构的数据来说,采用下标访问比较好。
需要循环链表结构的数据时,一定不要使用普通for循环,即需要指针访问时,使用foreach
另外foreach不支持在循环中添加删除操作,因为在使用foreach循环的时候数组(集合)就已经被锁定不能被修改,否则会报出java.util.ConcurrentModificationException异常
遍历期间得到的是对象,没有索引位置信息,因此没办法将指定索引位置对象替换为新对象,也就是不能赋值。
可以使用Iterator来进行操作
@Test
public void test5(){
List<Long> l=new ArrayList<Long>();
l.add(1L);
l.add(2L);
Iterator<Long> iterator=l.iterator();
while(iterator.hasNext()){
Long next = iterator.next();
if(next.intValue()==1){
iterator.remove();
}
}
for(int i=0;i<l.size();i++){
System.out.println(l.get(i));
}
}
打印出来是2
总结:
对于数结构的集合类可以使用普通for循环,效率高,因为for循环采用下标访问,for循环可以替换指定位置元素
对于需要指针访问时,即非数组结构的集合类,可以使用foreach或Iterator,for循环根据角标效率较低
如果要添加或删除集合中的数据使用Iterator
for循环break,return,continue
public static void main(String[] args){
br();
re();
con();
}
public static void br(){
for(int i=0;i<10;i++){
if(i==5){
System.out.print(i);
break;//循环结束,方法继续执行
}
System.out.print("第"+i);
}
System.out.println("哈哈");
}
public static void re(){
for(int i=0;i<10;i++){
if(i==5){
System.out.print(i);
return;//方法结束,可以带返回值
}
System.out.print("第"+i);
}
System.out.println("哈哈");
}
public static void con(){
for(int i=0;i<10;i++){
if(i==5){
System.out.print(i);
continue;//进行下一次循环
}
System.out.print("第"+i);
}
System.out.println("哈哈");
}
增强for
l引入增强for循环的原因:抛弃Iterator
lfor/in语句的适用范围
- 遍历数组
- 遍历实现Iterable接口的集合类
l语法格式:
for(变量类型 变量 :需迭代的数组或集合){
}
增强for底层是使用迭代器实现的。
使用它的时候只能进行遍历操作,而不能像List中通过get方式可以对某个元素进行精确控制。
什么样的类可以被增强for操作? 只要实现Iterable接口就可以。
这个接口代表是可以被增强for操作的。
数组
数组本质是一个java类
数组变量的值为首地址
数组是用于存储同一类型数据的一个容器。数组一旦定义,长度不可变
数组中可以存放基本数据类型数据也可以存放引用类型数据
直接输出数组变量会自动调用toString方法
数组中存放基本数据类型时,存放的是值,如果未赋初值,默认初始化为0;
数组中存放引用类型数据时,存放的是数据的引用,默认初始化为null。
数组的类名
数组的类型和它存储的数据类型有关
数组的类型可以通过arr.getClass().getName()获得,arr为数组对象。
[I [Ljava.lang.String
数组的类名总是以左中括号开头,然后是不同的标示。例如int就是I,字符串类型的数组则是Ljava.lang.String
使用一个java数组的步骤:
- 声明数组,使用一个引用来操作数组。
- 使用new关键字来为数组穿件所需的空间,并返回一个引用的值,还可以用{}符号来为数组赋初值。
- 使用数组下标对数组的值进行操作。
数组定义的方法
//静态定义
int[] arr = {23,4,67,198,3};
int[][] ma = { {1,2,3},{4,5,6}};
//动态定义
int arr2 [] = new int[10];
int[] arr3 = new int[]{1,3,5,7};
int[][] n = new int [2][]; //不常用,但正确
int[] array[] = new int[3][4]; //不常用,但正确
不能既定义长度又定义具体元素
数组的静态方法
Arrays.sort(char[] a);对数组a中的元素进行升序排序,a数组变为排序后数组
Arrays.sort(Object[] a):同上,其他类型数组也是
Arrays.toString(Object[] a):返回数组的字符串形式
Arrays.asList(T... a) : 返回一个受指定数组支持的固定大小的列表。返回类型List
拷贝数组
使用System.arraycopy()方法,如System.arraycopy(arr,0,arr2,0,arr.length);
创建一个新的数组实例,然后把数据一一装填进去
二维数组
因为数组本质是一种java类,这种特性使多维数组可以无限扩展维度,并且每个维度的长度可以参差不齐。
二维数组是:先创建一个数组,然后该数组的元素再引用另外一个数组,而另外的这个数组中存放的就是目标内容。
多维数组的长度不固定,可以动态变化
二维数组的应用
int[][] arr= new int[3][];
arr[0]=new int[]{1,2};
arr[1]=new int[]{1,2,3};
arr[2]=new int[]{1,2,3,4};
数组的遍历方法:
- for循环:
for(int i=0; i<arry.length;i++) System.out.print(arry[i]);
二维
for(int i=0;i<arry.length;i++)
for(int j=0;j<arry[i].length;j++)
System.out.print(arry[i][j]);
- foreach循环:
for(int i : arry){System.out.print(i)}; - i是方便输出定义的变量类型跟数组元素类型一致,arry为遍历的数组名
二维for(int[] i: arry)
for(int j : i)
System.out.print(j)
Arrays.toString方法:
String s="sdf.dfdsf,dfsdf dfd";
String[] s1=s.split("[., ]");
System.out.println(Arrays.toString(s1));
结果:[sdf, dfdsf, dfsdf, dfd]
int[] i=new int[]{1,2,3,4};
Integer[] t=new Integer[]{1,2,3,4};
System.out.println(Arrays.asList(t));
System.out.println(Arrays.toString(t));
System.out.println(Arrays.toString(i))
System.out.println(Arrays.asList(i));
打印结果:[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4]
[[I@5483cd]
动态参数
l测试JDK中具有可变参数的类Arrays.asList()方法。分别传多个参、传数组,传数组又传参的情况。
- 注意:传入基本数据类型数组的问题。
l从JDK 5开始, Java 允许为方法定义长度可变的参数。语法:
public void foo(int … args){
}
l注意事项:
- 调用可变参数的方法时, 编译器将自动创建一个数组保存传递给方法的可变参数,因此,程序员可以在方法体中以数组的形式访问可变参数
- 可变参数只能处于参数列表的最后, 所以一个方法最多只能有一个长度可变的参数
声明 类型... 变量名
这个变量本质就是一个数组.
在传递参数时,可以传递多个值,也可以传递一个数组。
注意:动态后面不能有其它的参数,可以在前面声明。
Arrays下的asList就是使用了动态参数,
它的作用是将数组变成List集合。
注意:由数组变成的集合不能改变集合长度。
如果数组中的元素是基本类型,那么它会将数组装入到集合中做为元素。
如果是引用类型,将数组中的元素做为集合的元素。
接收键盘输入
1、java.util.Scanner,文本扫描器
Scanner sc = new Scanner(System.in);//定义对输入流监听
String 输入的信息 = sc.nextInt();//获得整型,sc.next();//获取字符串到第一个空白符为止sc.nextFloat(); //接收float型数据 ,sc.nextLine()//接收一行,
String s ="12-23-12.3"
Scanner sc = new Scanner(s);//对字符串扫描监听
sc.useDelimiter("-");//将此扫描器的分割模式设为字符串“-”
sc.nextInt()获得12,sc.nextInt()获得23,sc.nextDouble()获得12.3
- int x = Integer.parseInt(args[0]);//args[]可以接收在java 类名后写上要输入的字符串用空格分开。执行java以后x就已经被赋值
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
out.println("你输入的是:"+br.readLine());
4、回车代表两个字符'\r'和'\n'读的时候先读'\r'再读'\n'
this关键字
- this关键字是一个对象的引用,this出现在方法内,具体引用哪个对象,就看调用方法的是哪个对象
2、this对象后面跟上 () 调用的是本类中的对应参数的构造方法。必须定义在构造方法的第一行。因为构造方法是用于初始化的,所以初始化动作一定要执行。否则编译失败。
3、this也可以当做实参进行传递
创建对象过程
Person p = new Person(); 虚拟机做了什么事?
我们先假设是第一次使用该类,这样的话new一个对象就可以分为两个过程:加载并初始化类和创建对象。
一、类加载过程(第一次使用该类)
java是使用双亲委派模型来进行类的加载的,所以在描述类加载过程前,我们先看一下它的工作过程:
双亲委托模型的工作过程是:如果一个类加载器(ClassLoader)收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委托给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父类加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需要加载的类)时,子加载器才会尝试自己去加载。
使用双亲委托机制的好处是:能够有效确保一个类的全局唯一性,当程序中出现多个限定名相同的类时,类加载器在执行加载时,始终只会加载其中的某一个类。
1、加载
由类加载器负责根据一个类的全限定名来读取此类的二进制字节流到JVM内部,并存储在运行时内存区的方法区,然后将其转换为一个与目标类型对应的java.lang.Class对象实例
2、验证
格式验证:验证是否符合class文件规范
语义验证:检查一个被标记为final的类型是否包含子类;检查一个类中的final方法是否被子类进行重写;确保父类和子类之间没有不兼容的一些方法声明(比如方法签名相同,但方法的返回值不同)
操作验证:在操作数栈中的数据必须进行正确的操作,对常量池中的各种符号引用执行验证(通常在解析阶段执行,检查是否可以通过符号引用中描述的全限定名定位到指定类型上,以及类成员信息的访问修饰符是否允许访问等)
3、准备
为类中的所有静态变量分配内存空间,并为其设置一个初始值(由于还没有产生对象,实例变量不在此操作范围内)
被final修饰的static变量(常量),会直接赋值;
4、解析
将常量池中的符号引用转为直接引用(得到类或者字段、方法在内存中的指针或者偏移量,以便直接调用该方法),这个可以在初始化之后再执行。
解析需要静态绑定的内容。 // 所有不会被重写的方法和域都会被静态绑定
以上2、3、4三个阶段又合称为链接阶段,链接阶段要做的是将加载到JVM中的二进制字节流的类数据信息合并到JVM的运行时状态中。
5、初始化(先父后子)
5.1 为静态变量赋值
5.2 执行static代码块
注意:static代码块只有jvm能够调用
如果是多线程需要同时初始化一个类,仅仅只能允许其中一个线程对其执行初始化操作,其余线程必须等待,只有在活动线程执行完对类的初始化操作之后,才会通知正在等待的其他线程。
因为子类存在对父类的依赖,所以类的加载顺序是先加载父类后加载子类,初始化也一样。不过,父类初始化时,子类静态变量的值也有有的,是默认值。
最终,方法区会存储当前类类信息,包括类的静态变量、类初始化代码(定义静态变量时的赋值语句 和 静态初始化代码块)、实例变量定义、实例初始化代码(定义实例变量时的赋值语句实例代码块和构造方法)和实例方法,还有父类的类信息引用。
二、创建对象
1、在堆区分配对象需要的内存
分配的内存包括本类和父类的所有实例变量,但不包括任何静态变量
2、对所有实例变量赋默认值
将方法区内对实例变量的定义拷贝一份到堆区,然后赋默认值
3、执行实例初始化代码
初始化顺序是先初始化父类再初始化子类,初始化时先执行实例代码块然后是构造方法
4、如果有类似于Child c = new Child()形式的c引用的话,在栈区定义Child类型引用变量c,然后将堆区对象的地址赋值给它
需要注意的是,每个子类对象持有父类对象的引用,可在内部通过super关键字来调用父类对象,但在外部不可访问
补充:
通过实例引用调用实例方法的时候,先从方法区中对象的实际类型信息找,找不到的话再去父类类型信息中找。
如果继承的层次比较深,要调用的方法位于比较上层的父类,则调用的效率是比较低的,因为每次调用都要经过很多次查找。这时候大多系统会采用一种称为虚方法表的方法来优化调用的效率。
所谓虚方法表,就是在类加载的时候,为每个类创建一个表,这个表包括该类的对象所有动态绑定的方法及其地址,包括父类的方法,但一个方法只有一条记录,子类重写了父类方法后只会保留子类的。当通过对象动态绑定方法的时候,只需要查找这个表就可以了,而不需要挨个查找每个父类。
1将Person.class文件加载到方法区内存
2执行main方法时,在虚拟机栈内存中开辟了main方法的空间(压栈-进栈),然后在main方法的栈区分配了一个变量p。
3.在堆内存中开辟一个实体空间,分配了一个内存首地址值。(new操作符开空间并返回对象的引用)
4.在该实体空间中进行属性的空间分配,并进行了默认初始化。
5.对空间中的属性进行显示初始化。
6.进行实体的构造代码块初始化。
7.调用该实体对应的构造方法,进行构造 方法初始化。
8将对象的首地址给变量p
p的值是该对象的运用等价于不具有地址运算的指针。
对象的生命周期
当对象被创建到失去所有的引用(没有任何一个变量记住它的首地址),这期间我们称之为对象的生命周期
对象的生命周期结束就会成为垃圾对象,等待虚拟机的回收
构造代码块和构造方法
1、构造代码块:也称为初始化代码块,是给所有的对象进行初始化,也就是说,所有的对象都会调用一个代码块。只要对象一建立。就会调用这个代码块。
2、构造方法:是给与之对应的对象进行初始化。它具有针对性。
3、静态代码块:就是一个有静态关键字标示的一个构造代码块区域。定义在类中。
作用:可以完成类的初始化。静态代码块随着类的加载而执行,而且只执行一次(new 多个对象就只执行一次)。如果和主方法在同一类中,优先于主方法执行。
4、静态代码块、构造代码块、构造方法同时存在时的执行顺序:静态代码块—>构造代码块 —>构造方法;
普通代码块:在方法或语句中出现的{}就称为普通代码块。普通代码块和一般的语句执行顺序由他们在代码中出现的次序决定--“先出现先执行”如:public void a(){int a =1;{int b=2;}}。其中的{}的内容为普通代码块内容
构造代码块:直接在类中定义且没有加static关键字的代码块称为{}构造代码块。构造代码块在创建对象时被调用,每次创建对象都会被调用,并且构造代码块的执行次序优先于类构造函数。
生成Java帮助文档:
命令格式:javadoc –d 文件夹名 –author –version *.java
/** //格式
*类描述
*@author 作者名
*@version 版本号
*/
/**
*方法描述
*@param 参数描述
*@return 返回值描述
*/
垃圾回收机制
垃圾回收机制是java相对c++的一种巨大改进,它避免了因为程序员忘记释放内存造成的内存溢出的错误。
c语言没有把堆的分配和释放做到语言层次,它对堆空间对象的操作是通过其库函数malloc()和free()来实现的;而c++直接把堆空间对象的分配和释放做到语言层次。使用new和delete语句,java是java虚拟机来做释放。
目前大多数JVM都实现了自动垃圾回收机制,只是各自的实现算法不同。
1.当对象被作为垃圾回收时,虚拟机会自动调用finalize方法(可以自己进行定义),用于释放一些资源。如果将要被回收的对象覆盖了finalize方法会掉用其finalize方法。
2.通过调用System.gc()方法可以人工进行垃圾回收
异常处理
整体说明
异常处理是一种机制,用于处理在程序执行过程中可能发生的异常情况,以确保程序能够优雅地处理这些问题而不会崩溃。
-
异常的类型:
- Java中的异常分为两种类型:已检查异常(Checked Exceptions)和未检查异常(Unchecked Exceptions)。
- 已检查异常必须在方法签名中显式声明或捕获,否则会导致编译错误。例如,IOException。
- 未检查异常通常是RuntimeException的子类,不要求在方法签名中显式声明或捕获。例如,NullPointerException。
-
try-catch块:
- 使用
try块来包围可能引发异常的代码块。 - 使用
catch块来捕获并处理特定类型的异常。一个try块可以有多个catch块,按照从上到下的顺序匹配异常类型。 catch块中可以执行异常处理逻辑,例如记录错误、恢复程序状态或抛出新的异常。
- 使用
-
finally块:
finally块是可选的,用于包含在无论是否发生异常时都必须执行的代码。例如,释放资源(如文件或数据库连接)。
-
throws关键字:
- 在方法签名中使用
throws关键字来声明方法可能抛出的已检查异常。这将通知调用者处理这些异常或继续向上层抛出。
- 在方法签名中使用
-
throw关键字:
- 使用
throw关键字手动抛出异常。这通常用于在特定条件下引发异常。
- 使用
-
异常类层次结构:
- Java的异常类构成了一个层次结构,根类是
Throwable,分为Error和Exception两个主要子类。Error通常表示严重的问题,不应被捕获和处理,而Exception用于表示可捕获和处理的问题。
- Java的异常类构成了一个层次结构,根类是
-
自定义异常:
- 可以创建自定义异常类,扩展
Exception或其子类,以表示特定应用程序的异常情况。
- 可以创建自定义异常类,扩展
-
异常处理最佳实践:
- 尽量避免捕获过于宽泛的异常,而应该捕获特定的异常类型。
- 不要忽略异常,至少应该记录异常信息。
- 使用
finally块来确保资源释放,即使发生异常也能执行。
自定义异常说明
自定义异常通常继承自以下两种类之一:
Exception类:大多数自定义异常应该继承自Java的Exception类或其子类。Exception是一个通用的异常基类,适用于大多数情况。你可以根据需要选择继承Exception,以表示应用程序中的特定异常情况。
public class CustomException extends Exception {
// 构造函数和自定义异常的逻辑
}
RuntimeException类:如果你的自定义异常表示的是运行时错误,通常可以继承自RuntimeException或其子类。运行时异常不需要在方法签名中声明或捕获,它们通常由程序员的错误引起,例如空指针异常(NullPointerException)等。
public class CustomRuntimeException extends RuntimeException {
// 构造函数和自定义异常的逻辑
}
try catch用法详细说明
try {
// 可能引发异常的代码块
} catch (ExceptionType1 e1) {
// 处理 ExceptionType1 类型的异常
} catch (ExceptionType2 e2) {
// 处理 ExceptionType2 类型的异常
} finally {
// 可选的 finally 块,用于无论是否发生异常都会执行的代码
}
try-with-resources用法
是Java中一种用于自动关闭资源的语法结构。它用于确保在代码块结束时释放资源,例如文件、数据库连接或网络套接字,而无需显式调用关闭方法。try-with-resources 使用的资源必须实现 AutoCloseable 接口,这个接口有一个 close() 方法用于释放资源。
try (ResourceType resource = new ResourceType()) {
// 使用资源的代码块
} catch (ExceptionType e) {
// 处理异常
}
在这个结构中,ResourceType 是实现了 AutoCloseable 接口的资源类型,它将在代码块结束时自动关闭。不管代码块是否正常执行完成,都会自动调用资源的 close() 方法释放资源。
示例:使用 try-with-resources 来读取文件内容:
try (FileReader reader = new FileReader("example.txt")) {
int character;
while ((character = reader.read()) != -1) {
System.out.print((char) character);
}
} catch (IOException e) {
// 处理读取文件时的异常
}
在上述示例中,FileReader 是一个实现了 AutoCloseable 接口的资源,因此在 try 块结束时,不需要显式调用 close() 方法来关闭文件。
try-with-resources 简化了资源管理,减少了资源泄漏的风险,并提高了代码的可读性。它在Java 7及更高版本中可用,是一种推荐的资源管理方式。
其他总结
instanceof运算符
public boolean equals(Object anObject ){
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
if(anotherString.equals("123456")){
return true
}
return false
}
return false
}
对象是否是特定类的一个实例
long类型和int类型相加
@Test
public void test4(){
int a=Integer.MAX_VALUE:
int d=1+a;
System.out.printIn(d);
}
结果:-2147483648
@Test
public void test4(){
int a=Integer.MAX VALUE;
long c=1;
long d=c+a;
System.out.println(d);
}
结果:2147483648
@Test
public void test4(){
int a=Integer.MAX_VALUE;
long d=1+a;
System.out.printIn(d);
}
结果:-2147483648
@Test
public void test4(){
int a=Integer .MAX_VALUE;
long d=(long)1+a;
System.out.printIn(d);
}
结果:2147483648
总结:只要相加的数中有一个long类型结果就是long类型
对double值进行四舍五入,保留两位小数
public static double formatDouble1(double d) {
return (double)Math.round(d*100)/100;
}
两个整数相除四舍五入保留一位字符串
String result = "";
float num =(float)a/b;
DecimalFormat df = new DecimalFormat("0.0");
result = df.format(num);
随机
(int)(Math.random()*10)
0-10的随机整数
jar包
java.lang包
在rt.jar中,rt.jar在jdk中
加入jar包的方法
maven管理maven仓库配合pom.xml文件maven项目
web项目放到WEB-INF目录下的lib文件夹下,会自动buildPath
java项目建立lib文件夹,拷贝jar包到里面,右键选择buildPath-add to build path
接口中方法为什么不写修饰符
java定义的接口方法默认含有public abstract
其余类中方法不加修饰符默认为default
查看对象的大小
maven中引入
<dependency>
<groupId>com.carrotsearch</groupId>
<artifactId>java-sizeof</artifactId>
<version>0.0.5</version>
</dependency>
Integer a=10;
System.out.println(ObjectSizeCalculator.getObjectSize(a));
打印出来是16,即16B
单位是B,即字节
Java基本类型长度及对应对象的字节长度
基本类型 长度 the size of an object
Int 4 16
Short 2 16
Long 8 24
Byte 1 16
Character 1 16
Float 4 16
Double 8 24

浙公网安备 33010602011771号