1、Java的注释
Java一共分为以下3种形式
① // : 单行注释; ② /* ... */ : 多行注释; ③ /** ... */ : 文档注释;(使用IED,生成文档时,若.java文件使用的是UTF-8编码时需要 -encoding UTF-8 -charset UTF-8)
2、标识符与关键字
Java中的标识符有类名、属性名称、方法名称等等,标识符的定义要求是:标示符由字母、数字、_、$、¥组成,其中不能以数字开头,不能是Java中的关键字
Tips:
- 在编写的时候尽量不要使用数字,例如i1、i2
- 命名尽量有意义,不要使用"a" "b"这样的标识符。例如:Student、Math这些都属于有意义的内容;
- Java中标识符是区分大小写的,例如:mldn、Mldn、MLDN表示3个不同的标识符
- 对于“$”符号有特殊的意义,不要去使用(A类中有一个B类,即B类是A类的内部类,则编译生成两个.class文件,分别为A.class和A$B.class,也就是说通此命名规范我们知道B类是A类的内部类)
- 永远不要用数字开头,而且尽可能不要包含其他符号
下面的标识符是合法的:
myName,My_name,Points,$points,_sys_ta,OK,_23b,_3_
下面的标识符是非法的:
#name(包含#),25name(数字开头),class(关键字),&time(包含&),if(关键字),67.9(数字开头和包含.),my name(包含空格)
关键字:Java中的关键字不需要强记,后面逐渐练习熟练后就会记住了
![](https://i-blog.csdnimg.cn/blog_migrate/f40b1d80b9c653a3e79301e4d66809b2.png)
- Java有两个未使用到的关键字:goto(在其他语言中表示无条件跳过)、const(在其他语言中表示常量);
- JDK1.4之后增加了assert关键字;
- JDK1.5之后增加了enum关键字;
- Java有3个特殊含义的标记(严格来讲不算是关键字):true、false、null
3、数据类型划分
Java数据类型分为引用数据类型和基本数据类型。引用数据类型(类似于C/C++的指针)在操作的时候必须要进行内存的开辟,如String、数组、用new创建的对象,基本数据类型不牵扯内存分配问题,基本数据类型有八种:byte、short、int、long、float、double、float、char。
![](https://i-blog.csdnimg.cn/blog_migrate/2c7841b63722c950929b1942505f8328.png)
![](https://i-blog.csdnimg.cn/blog_migrate/bd55b6e24a3a2bb2ed80db2cb986e401.png)
注意char类型取值范围应该为0~65535或者 \u0000 到 \uffff:
public static void main(String[] args) {
char cMin = Character.MIN_VALUE;
char cMax = Character.MAX_VALUE;
System.out.println((int)cMin);//0
System.out.println((int)cMax);//65535
}
常用的char值范围:
- 'A' (65) ~ 'Z' (90);
- 'a' (97) ~ 'z' (122)
- '0' (48) ~ '9' (57)
由此可知字母‘A’与‘a’相差32,所以可以利用简单的数据计算来实现大小写的转换
public static void main(String[] args) {
char c = 'A'+32;
System.out.println(c);//a
}
4、数据类型转换与数据溢出
关于数据类型的转换在开发中是经常遇到的问题,但实际开发中建议尽量避免使用强制类型转换,以免造成数据精度的丢失以及数据功能性的破坏。数据类型的转换有以下规律:
- 数据类型范围小与数据类型范围大的数据进行计算时,会自动转换为大范围的数据类型(例如:int类型和long类型计算时,由于int保存范围小则自动变为long类型。注意:byte、short类型的数据参与运算时会自动转换为int类型)
- 数据类型大的数据要变为数据类型小的数据,要进行强制类型转换。如:“(int) long类型变量”,表示将long类型变量转换为int类型变量。
- 引用数据类型范围由大到小,称为向下转型;由小到大,称为向上转型
数据类型溢出:
当整数的数据大小超出了可以表示的范围,而程序中又没有做数值范围的检查时,这个整型变量所输出的值将发生紊乱,且不是预期的运行结果。
![](https://i-blog.csdnimg.cn/blog_migrate/e55a4a4253858f8410be49c38d0214c2.png)
在进行数据类型强制时也可能发生数据溢出:
public static void main(String[] args) {
long l = 2147483648L;
int i = (int)l;
System.out.println(i);//-2147483648
}
5、运算符与优先级
Java中提供了许多运算符,大致可分为赋值运算符、算数运算符、关系运算符、逻辑运算符、条件运算符(三目运算符)、括号运算符、自增/自减运算符
![](https://i-blog.csdnimg.cn/blog_migrate/a3a606114f0b97ed13d7af7b04d0ae7d.png)
注意:byte、short可以参与++/--或者+=、-=、*=、/=运算,而且运算完成之后依然是原来的类型,Java底层已经对其进行了类型强制转换
与操作:&(普通与:依次执行判断两个条件)、&&(短路与:如果第一个条件false就不会执行第二个条件,即使第二个条件有运行时异常也不会执行报错)
![](https://i-blog.csdnimg.cn/blog_migrate/c5506693a220f03a8f3f59c910ce5e44.png)
public static void main(String[] args) {
int x = 1, y = 1;
if (x++ == 2 & ++y == 2) {
x = 7;
}
System.out.println("x=" + x + ",y=" + y); // x=2,y=2
}
===========================================================
public static void main(String[] args) {
int x = 1,y = 1;
if(x++==2 && ++y==2){
x =7;
}
System.out.println("x="+x+",y="+y); // x=2,y=1
}
或操作:|(普通或:依次执行判断两个条件)、||(短路或:如果第一个条件true就不会执行第二个条件,即使第二个条件有运行时异常也不会执行报错)
![](https://i-blog.csdnimg.cn/blog_migrate/331589c142acc69abaf3169dc6554c6b.png)
public static void main(String[] args) {
int x = 1,y = 1;
if(x++==1 | ++y==1){
x =7;
}
System.out.println("x="+x+",y="+y); // x=7,y=2
}
============================================================================
public static void main(String[] args) {
int x = 1,y = 1;
if(x++==1 || ++y==1){
x =7;
}
System.out.println("x="+x+",y="+y);// x=7,y=1
}
位运算中进制之间的转换(Java中二进制、八进制、十六进制开头符号分别用0b、0、ox表示,例如十进制155,二进制表示为0b10011011、八进制表示为0233、十六进制表示为0x9b):
![](https://i-blog.csdnimg.cn/blog_migrate/4c64e91fabaae8c970659d8d896b23f6.png)
用Java程序换算进制:二进制1表示,八进制——0~7,十进制——0~9,十六进制——0~9+a(10)~f(15)
十进制转十六进制:
public static void main(String[] args) {
//十进制转成十六进制:Integer.toHexString(int i)
System.out.println(Integer.toHexString(155));//9b
//十进制转成八进制:Integer.toOctalString(int i)
System.out.println(Integer.toOctalString(155));//233
//十进制转成二进制:Integer.toBinaryString(int i)
System.out.println(Integer.toBinaryString(155));//10011011
//十六进制转成十进制:Integer.valueOf(String s,int radix)
System.out.println(Integer.valueOf("9b", 16));//155
//八进制转成十进制
System.out.println(Integer.valueOf("233",8));//155
//二进制转成十进制
System.out.println(Integer.valueOf("10011011",2));//155
/*
* java.lang.Integer类可以直接将2,8,16进制直接转换为10进制
* integer.parseInt(String s,int radix)
* 使用第二个参数指定的基数,将字符串参数解析为有符号的整数
*/
System.out.println(Integer.parseInt("f", 16));//15
}
如何快速的计算出2的3次方?如果采用“2*2*2”的方式会进行数学的运算,显然不是最快的,这时可以使用位运算符即int i=2;i<<2;
运算符优先级没有必要强记,可以多使用"()"去改变优先级:
类别 | 操作符 | 关联性 |
---|---|---|
后缀 | () [] . (点操作符) | 左到右 |
一元 | + + - !〜 | 从右到左 |
乘性 | * /% | 左到右 |
加性 | + - | 左到右 |
移位 | >> >>> << | 左到右 |
关系 | >> = << = | 左到右 |
相等 | == != | 左到右 |
按位与 | & | 左到右 |
按位异或 | ^ | 左到右 |
按位或 | | | 左到右 |
逻辑与 | && | 左到右 |
逻辑或 | | | | 左到右 |
条件 | ?: | 从右到左 |
赋值 | = + = - = * = / =%= >> = << =&= ^ = | = | 从右到左 |
逗号 | , | 左到右 |
6、程序逻辑控制
①顺序结构
程序自上而下逐行执行,一条语句执行完后继续执行下一条语句,直到程序的末尾。
②选择(分支)结构
分支语句语法支持有:if(if,if...else,if...else if...else)、switch。如果if语句中只有一行代码,“{}”可以省略。简单的if...else语句可用三目运算代替。switch是多重选择语句,switch标签内容会依次与case标签内容进行比较,case语句内一般会有一个break用于终止switch语句(如果break省略会造成“case穿透现象”),如果比较内容成功则执行对应的case语句内容,否则执行default语句内容(default语句可以省略,但是不建议。break也可省略,但也不建议,default可以在switch语句的任意位置)。 注意:if可以判断布尔表达式,而switch只能够判断内容。
③循环结构
循环语句有:while(while循环和do...循环)和for循环 死循环:
while(true)
for(;;){} for(;true;){}
for(int i=1;i>=1;i++){}
拓展:增强for和迭代器:JDK1.5增加了增强for语法糖,是一种功能很强的循环结构,可以用来依次处理数组中的的每个元素(其他类型的元素集合亦可)而不必为指定下标而分心。
语法格式为: for(variable : collection) statement
下面我们用 foreach 来对数组和一个集合进行遍:
|
然后我们可以通过反编译工具,查看 class 文件内容:
|
很明显:
1、对于数组,foreach 循环实际上还是用的普通的 for 循环
2、对于集合,foreach 循环实际上是用的 iterator 迭代器迭代
迭代器:迭代器(Iterator)模式,又叫做游标模式,含义是提供一种方法访问一个容器对象中各个元素,而不需要暴露该对象的内部细节。Java通过提供Iterator和Iterable两个接口来实现集合类的可迭代性,迭代器主要的用法是:首先用hasNext()作为循环条件,再用next()方法得到每个元素,最后在进行相关的操作。
for循环与迭代器的对比:
* 效率上各有各的优势:
> ArrayList对随机访问比较快,而for循环中使用的get()方法,采用的即是随机访问的方法,因此在ArrayList里for循环快。
> LinkedList则是顺序访问比较快,Iterator中的next()方法采用的是顺序访问方法,因此在LinkedList里使用Iterator较快。
> 主要还是要依据集合的数据结构不同的判断。
7、方法的定义以及使用
方法又称为函数,方法是一段可以被重复调用的代码块。
语法格式:
修饰符 static 返回值类型 方法名(参数类型 参数变量,...){
方法体(本方法中要执行的若干操作);
[return [返回值];]
}
- java中有四种修饰符
Java中的修饰符访问权限 - 返回值类型可以是基本数据类型、引用数据类型,如果是了返回值,那么就必须使用return语句返回与数据类型对应的数据;
- 方法没有返回值类型void,可以不使用return返回内容,但是可以使用return结束方法调用。
- 方法名命名规范:第一个单词的首字母小写,之后的单词的首字母大写。
- 普通方法在本类主方法中可以直接调用,在其他类中通过对象名调用;静态方法可以直接通过“类名.方法名”调用
8、方法的重载与重写
方法的重载(overload)是指在同一个类中方法名称相同,参数的类型、个数或顺序不同。
- 在进行方法重载时一定要考虑到参数类型的统一,虽然可以实现重载方法返回不同的类型的操作,但是从标准的开发来讲,建议所有重载后的方法使用同一返回值类型。
- 方法重载的时候重点是根据参数类型及个数来区分不同的方法,而不是依靠返回值的不同确定的。
- 与普通方法一样,构造方法也可以重载
方法的重写(override)也称之为方法的覆写或方法的覆盖。定义:子类里面出现和父类相同的方法声明。方法声明相同:返回值类型、方法名、参数列表相同。
方法重写注意事项:
- 子类重写父类的方法,访问权限不能比父类低
- 子类的返回值类型必须要小于或者 等于父类的返回值类型。
- 子类抛出的异常类型要小于或者等于父类抛出的异常类型。 Exception(最坏) RuntimeException(小坏)
- 子类的私有方法不能重写
- 子类的静态方法,子类必须通过静态进行重写(不是真的重写)
方法重写与方法重载的区别
![](https://i-blog.csdnimg.cn/blog_migrate/b11f8f40ff8d2ca310ac9007740dc187.png)
9、方法的递归调用
递归调用是一种特殊的调用形式,指的是方法自己调用自己的形式。递归调用注意以下两点:
- 必须有结束条件
- 每次调用时都需要改变传递的参数
![](https://i-blog.csdnimg.cn/blog_migrate/aa7e102e3582c2655b5977bebe461576.png)
常见的递归小案例:
public static void main(String[] args) {
System.out.println(sum(100));//5050
System.out.println(getSum(20));//6765
}
//计算1~num之和
public static int sum(int num){
if(num==1)
return 1;
return num+sum(num-1);
}
//兔子问题,斐波那契数列
public static int getSum(int num){
if(num==1||num==2)
return 1;
return getSum(num-1)+getSum(num-2);
}
简单的编程小练习: