java初级(简单常识1)
标识符
- 标识符用来给包,类,方法以及变量命名的
- 标识符由字母,数字,下划线’_‘和美元符’$'号组成,不以数字开头
这里的字母:因为java用unicode编码,因此不仅仅指英文字母,还包含汉字等等,但不建议 - java标识符对大小写敏感,并且无长度限制
- 标识符不可以是java关键字
标识符命名规范(规范不是规则,但建议这么做)
- 表示类名的标识符:每个单词首字母大写
- 见名知意
- 表示方法和变量的标识符:驼峰原则:第一个单词小写,第二个单词开始首字母大写
变量(分为三类)
- 局部变量(local variable)
方法或语句块内部定义的变量,生命周期从声明位置开始到方法或语句块执行完毕为止
在使用前必须先声明,初始化(赋值)在使用,局部变量不会自动有默认值 - 成员变量(也叫实例变量member variable)
方法外部,类的内部定义的变量,从属于对象,生命周期伴随对象始终
如果不自行初始化,则会自动初始化为该类型的默认初始值数据类型 初始值 int 0 double 0.0 char ‘\u0000’ boolean false - 静态变量(类变量 static variable)
使用static定义.从属于类,生命周期伴随类始终,从类加载到卸载
常量(字面常量和自定义常量)
在java语言中,主要利用关键字final来定义一个常量,常量一旦被初始化后不能再更改其值
声明格式:final type varName = value;
为了更好区分和表述,一般将1,2,3,‘a’,true,false,"helloword"等称为字面常量,而使用final修饰的PI等称为符号常量
注意
- 所有变量,方法,类名:见名知意
- 类成员变量:首字母小写和驼峰原则:monthSalary
- 局部变量:首字母小写和驼峰原则
- 常量:大写字母和下划线:MAX_VALUE
- 类名:首字母小写和驼峰原则:Man,GoodMan
- 方法名:首字母小写和驼峰原则:run(),runRun()
数据类型
基本数据类型
- 整型变量/常量(byte,short,int,long,分别占用1,2,4,8个字节)
java语言整型常量的四种表示形式
十进制整数,如10,-50,0
八进制整数,要求以0来头,如015
十六进制数,要求以0x或者0X开头,如0x15
二进制数,要求以0b或者0B开头,如0b01110011 - 浮点型变量/常量(float,double,分别占用4和8字节),写个浮点数默认为double
浮点类型常量有两种表示形式
十进制数形式,例如:3.14,314.0
科学计数法形式,如314e2(表示314*10的二次方),314E-2
注意
浮点类型是不精确的,不要用于比较
如果想要精确,可以使用java.math包下边的两个类:BigInteger类和BigDecimal类,
二者可以处理任意长度的数值,前者实现了任意精度的整数运算,后者实现了任意精度的浮点运算.
示例一
float f = 0.1f;
double d = 1.0/10;
System.out.println(f==d); //结果为false
示例二
float d1 = 43432423f;
float d2 = d1+1;
if(d1==d2){
System.out.println("d1==d2); //结果为d1==d2
}else{
System.out.println("d1!=d2);
}
- 字符型变量/常量 (char,占用2个字节)
char类型用来表示在Unicode编码表中的字符.而Unicode编码被设计用来处理各种语言的文字,占两个字节,可以允许有65536个(0-65535)字符,通常用从’\u0000’到’\uFFFF’之间的十六进制值来表示,前缀为u表示Unicode
还可以为转义字符
char c2 = ‘\n’; --> 对应的Unicode值为:\u0008 - 布尔boolean类型变量/常量,有两个常量值,true和false,在内存中占用一位(不是一个字节)
不可以使用0或者非0的整数代替true和false,这点和C语言不同
(Less is More!),不要这样写: if (flag == true), 推荐写法: if(flag) 或者 if(!flag)
运算符
算术运算符
算数运算符中+, -, *, /, %属于二目运算符
二元运算符的运算规则:
整数运算:
1. 如果两个操作数有一个为long类型,则结果也为long
2. 没有long时,结果为int.即使操作数全为short,byte,结果也是int
浮点运算:
1.如果两个操作数有一个为double,则结果为double
2.只有两个操作数都是float,结果才为float
取模运算:
1. 其操作数可以为浮点数,一般使用证书,结果是"余数",运算结果的符号和左操作数相同
2. 算数运算符中++,- -为一元运算符,该类运算符只需要一个操作数
关系运算符
关系运算结果为布尔值:true/false
1.==和!=是所有(基本和引用)数据类型都可以使用
2. >, >=, <, <=仅针对数值类型(byte,short,int,long,float,double,char)
逻辑运算符
位运算符
&, |, ~, <<, >>, >>>
计算机表示数字正负不是用+ -加减号来表示,而是用最高位数字来表示,0表示正,1表示负
- 有符号右移>>(若正数,高位补0,负数,高位补1)
正数:例如4>>2
首先写出4的二进制数,因为是正数所以最高位为0,也就是第一个
0000 0000 0000 0000 0000 0000 0000 0100
右移两位得到(高位补0)
000000 0000 0000 0000 0000 0000 0000 01
结果为:1,右移n位也就是4/(2^n)
负数:例如-4>>2(高位补1)
首先写出-4的二进制数,因为是负数所以最高位为1
1000 0000 0000 0000 0000 0000 0000 0100
然后__写出-4补码__:保证符号位不变,其余位置取反加1(从右往左遇到第一个1,然后剩下的全部取反就是了)
1111 1111 1111 1111 1111 1111 1111 1100(补码)
右移2位: 在高位补1
1111 1111 1111 1111 1111 1111 1111 1111
根据补码写出原码才是我们所求的结果, 保留符号位,然后按位取反再加上1
100000 0000 0000 0000 0000 0000 0000 00(取反后的结果)
100000 0000 0000 0000 0000 0000 0000 01(再加1)
结果为:-1 - 无符号右移>>>(不论正负,高位均补0)
正数:例如4>>>2
与4>>2的运算相同,结果也为1
负数:例如-4>>>2
首先写出-4的二进制数
1000 0000 0000 0000 0000 0000 0000 0100
然后写出-4补码:保证符号位不变,其余位置取反加1(从右往左遇到第一个1,然后剩下的全部取反就是了)
1111 1111 1111 1111 1111 1111 1111 1100(补码)
右移2位:在高位补0
0011 1111 1111 1111 1111 1111 1111 1111
结果为:1073741823
字符串运算符 (+)
两边操作数都是数,则为加号,任一个是字符串时,则字符串连接
String s1 = "3";
int x = 4;
int y = 5;
char c = 'a';
char d = 'b';
System.out.println(s1+x); //34
System.out.println(s1+x+y); //345
System.out.println(x+y+s1); //93
System.out.println(c); //a
System.out.println(c+1); //98
System.out.println(c+d); //195
System.out.println(""+c+d); //ab
运算符优先级
注意
用小括号()来组织
逻辑优先级:
逻辑非>逻辑与>逻辑或 (易错)
自动类型转换
指的是容量小的数据类型可以自动转换为容量大的数据类型
这里容量大或者小指的是:范围的大小,而不是字节数大小.例如.long占用8个字节,而float占用4个字节,long是可以自动转换为float的
可以将整型常量直接赋值给byte,short,char等类型变量,而不需要强制类型转换,只要不超出其表数范围即可!
short b = 12; //合法
short b = 123456;//超出了short的表数范围,short占两个字节
注意
基本数据类型常见错误:
- 操作比较大的数时,要留意是否溢出
int money = 1000000000;//10亿
int years = 20;
int total = money*years;
System.out.println("total="+total);//int类型的total发生溢出
long total2 = money*years;
System.out.println("total2="+total2);//虽然total2为long,但右边结果先算为int
long total3 = (long)money*years;
System.out.println("total3="+total3);//先提升范围,整型运算中,有long结果为long
- 不要命名名字为l的变量,l容易与数字1混淆,long类型使用大写L
带标签的break和continue
“标签"是指后面跟一个冒号的标识符,例如"label:” 对java来说唯一用到标签的地方是在循环语句之前
而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环,由于break和continue关键字通常只中断当前循环,但若随同标签使用,他就会中断到存在标签的地方.
示例一:打印101-150
public...
...main
outer:for(int i=101;i<150;i++){
for(int j=2;j<=Math.sqrt(i);j++){
if(i%j==0){
continue outer;
}
}
System.out.println(i+"\t");
}
方法
注意
- java中进行方法调用中传递参数时,遵循值传递的原则(传递方法的副本)
- 基本类型传递的是该数据值得copy值
- 引用类型传递的是该对象引用的copy值
方法的重载
重载的方法,实际是完全不同的方法,只是名称不同而已,调用时可以区分
构成方法重载的条件:
1. 不同的含义:形参类型,形参个数,形参顺序不同
2. 只有返回值不同不构成方法的重载
3. 只有形参的名称不同,不构成方法的重载
递归
自己调用自己
递归结构包括两个部分:
- 定义递归头. 解答:什么时候不调用自身方法,如果没有头,将陷入死循环,也就是递归的结束条件
- 递归体. 解答:什么时候需要调用自身方法
示例一:求阶乘的方法
public long factorial(int n){
if(n==1){ //递归头
return 1;
}else{ //递归体
return n*factorial(n-1);
}
}
注意
任何能使用递归解决的问题也能用迭代解决.当递归方法可以更加自然地反映问题,并且易于理解和调试,并且不强调效率问题时,可以采用递归
在要求高性能的情况下尽量避免使用递归,低估调用既花时间又耗内存
if(n==1){ //递归头
return 1;
}else{ //递归体
return n*factorial(n-1);
}
}
注意
任何能使用递归解决的问题也能用迭代解决.当递归方法可以更加自然地反映问题,并且易于理解和调试,并且不强调效率问题时,可以采用递归
在要求高性能的情况下尽量避免使用递归,低估调用既花时间又耗内存