前言:这一章是JAVA语言最为基础的东西,因为基础,显得他们尤为重要,其中更是有一些我们平时不太注意就会让我们栽跟头的地方。
JAVA语言基础
Java语言的构成:关键字、标识符、运算符、注释、常量与变量、运算符、语句、函数、数组。我们来简单的介绍下,并把他们的注意点说一下。
1.关键字
关键字就是被java赋予了特殊含义的单词,这些单词自从被java翻了牌子后,就成为了java的后宫佳丽中的一员,我们就不能把他们夺过来定义成别的东西了,看一看常见的关键字:
(1) 用于定义数据类型的关键字有: byte、short、int、long、float、double、char、boolean、void
(2) 用于定义流程控制的关键字有if、else、switch、case、default、while、do、for、break、continue、return
(3) 用于定义访问权限修饰的关键字有:private、protected、public
(4) 用于定义类,函数,变量修饰符的关键字有:abstract、final、static synchronized
(5) 用于定义建立实例及引用实例,判断实例类型的关键字有:new、this、super、instanceof
(6) 用于异常处理的关键字有:try、catch、finally、throws
(7) 用于包的关键字有:package、inport
注意:“main”虽然不是关键字,但是他是java的小三,代表主函数名,一般我们也不染指
2.标识符
(1) 标识符是我们用来标识我们自己所定义的各种东西的,标识符有三个特点:
1> 标识符的组成只能是26个字母,数字,_和$
2> 数字是不可以作为标识符的开头的
3> 不可以使用关键字
注意点:java是严格区分大小写的,所以A和a代表两个标识符
(2) Java中的名称规范:
1> 包名:所有单词首字母小写
2> 类名接口名:所有单词首字母大写。
3> 变量名和函数名:第一个单词首字母小写,第二个单词开始每个单词首字母大写。
4> 常量名:所有字母都大写,多个单词时每个单词用下划线连接。
3.注释
(1)一个好的程序员是绝不会不写注释的,注释的三种格式:
单行注释://注释内容
多行注释:/*注释内容*/
文档注释:/**注释内容*/
(2)我们重点说明一下文档注释,文档注释用于描述我们所写的程序,就像一个程序的说明书,我么可以利用javadoc.exe来提取出来。
我们来看一下怎样给一个类加文档注释:
/**
*建立一个用于操作数组的类,例如:排序,求最值等
*@author 小宏
*@version v1.0
*/
public class ArrayTool
{
private ArrayTool(){}
/**
*对数组进行获取最大值的操作
*@param arr 接收一个元素为int型数组
*@return Max 返回一个最大值
*/
public static int getMax(int[] arr)
{
int Max = 0;
for(int i=1;i<arr.length;i++)
{
if(arr[Max]<arr[i])
{
Max = i;
}
}
return arr[Max];
}
/**
*对数组进行排序操作
*@param arr 接收一个元素为int型数组
*/
public static void selectArray(int[] arr)
{
for(int i=0;i<arr.length-1;i++)
{
for(int j=i+1;j<arr.length;j++)
{
if(arr[i]>arr[j])
swap(arr,i,j);
}
}
}
/**
*对数组中的元素进行换位操作
*@param arr 接收一个元素为int型数组
*@param x 接收一个较小的数组角标
*@param y 接收一个较大的数组角标
*/
private static void swap(int[] arr,int x,int y)
{
int temp = arr[x];
arr[x]=arr[y];
arr[y]=temp;
}
/**
*对数组进行字符串化操作
*@param arr 接收一个元素为int型数组
*@return str 返回一个字符串化的数组
*/
public static String arrayToString(int[] arr)
{
String str = "[";
for(int i=0;i<arr.length;i++)
{
if(i<arr.length-1)
str = str +arr[i]+",";
else
str = str+arr[i]+"]";
}
return str;
}
/**
*给定一个数组元素可以找寻出他的角标
*@param arr 接收一个元素为int型数组
*@param key 接收需要找寻角标的数组元素
*@return index 返回寻找元素的角标
*/
public static int getIndex(int[] arr,int key)
{
for(int i=0;i<arr.length;i++)
{
if(arr[i]==key)
return i;
}
return -1;
}
}
在我们的doc命令行中找到我们java文件所在目录,让我们来看一看javadoc的用法:
javadoc [选项] [软件包名称] [源文件] [@files]
在我的doc命令行下输入:
javadoc -dmyhelp ArrayTool.java -version –author,然后在当前目录就出现了一个“myhelp”文件夹,里面就存放了一堆的网页文件,我们打开index.html文件,就可以看我们写的类的注释是什么个样子。
4.变量与常量
(1) 常量
常量就是不会改变的一个值,我们定义一个常量的标识符时他所有的字母都是大写的,一般我们如果要定义一个常量,通常要加一个修饰符:final,final表示是最终的,不可被改变的例如:
final int AGE = 100;
注意:null也是一个常量,只有一个数值null
(2) 变量
变量就是内存中的一个存储区域,我们给他定义一个名字,定义这个区域能放什么类型的值。
① 而数据数据类型分为基本数据类型和引用数据类型,基本数据类型有8个:
1> byte(字节):(占1个字节)范围:负的2的7次方到正的2的7次方减1即-128—+127;
2> short(短整型):(占2个字节)范围:负的2的15次方到正的2的15次方减1
3> int(整形):(占4个字节)范围:负的2的31次方到正的2的31次方减1,如果写整数,一般默认类型是int;
4> long(长整型):(占8个字节)范围:负的2的63次方到正的2的63次方减1。
5> float(单精度):精确程度低,占4个字节
6> double(双精度):精确程度高,占8个字节,默认情况下为double
7> char(字符型):占2个字节。
8> boolean型:
false,占1个字节
true,占1个字节。
注意点:
byte b = 3;
这个语句有什么注意点呢?我们知道b是个byte型的,3是个int型的,java首先去判断了一下3的长度,发现3可以被装到byte中,于是这句话是成立的,如果你写成:
byte b1 = 200;
编译器发现200超出了范围,就会报错,让我们来看一看下面的例子:
byte b1 = 2;
byte b2 = 3;
byte b3 = b1+b2;
这个也会报错,因为b3是个byte型的,b1加上b2后的值很有可能会超出byte范围,所以他报错了,为了解决这个问题,java给我们提供一个方式叫做强制转换,就是在把整个运算标识成我们需要的类型:
byte b3 = (byte)(b1+b2);
② 引用数据类型大多都是对象的引用,例如Person是一个类
Person p1 = new Person();
P1就是一个变量,他现在就代表着new Person()这个引用数据
除了类引用外,还有接口和数组。
5.运算符
运算符包括算数运算符、赋值运算符、比较运算符、逻辑运算符、位运算符、三元运算符
(1) 算数运算符:+、-、*、/、 %、++、--
/ 和%:/是除取整,%是除取余。例如5/2是2,5%2是1。
++和--运算:叫做自增和自减
以自加为例说明:
++在前代表先自加后操作,++在后代表先操作后自加,这里有一个很容易犯错的地方:
int a =3,b;
b = a++;
b的结果是3,a的结果是4,这句涉及到的具体的运算时怎样的呢,是a先把3赋值给b,然后a再自增的吗,不对!因为算术运算符的优先级大于赋值运算符,那么就因该是a自增完事后再赋值给b啊,那为什么b是3呢?原因是这样的:++在后的时候,java定义a要先参与其他运算,那么在内存中就为a设置一个临时存储区域来记录a原本的值,当a自增完事后,注意这时候a对应的有两个值(这是我自己理解的,我觉得只有这种方式才能说明了),一个是临时区域里的3,一个是真正存储的4,这时候赋值给b的不是4而是原来的保留值3。
int c =3;
c = c++;
c的结果是3,通过上一个实例我们知道当++在后时,c要先临时存储原来的值,然后自增,这时候我说c其实是对应两个值的,一个是3,一个是4,而这个4是c这个变量所真正对应的值,但是原来的临时存储值也要参与到赋值运算中来,c的值又被覆盖成3了,也就是c先自增得4,c的临时区域再赋值c,4被覆盖成3
(2) 比较运算符: <、<=、>、>=、==、!=
运行结果为boolean型变量,即false或者true。
(3) 逻辑运算符
逻辑运算符是用来连接两个bollean型的表达式
1> 与(&&或者&):同真为真,其它都为假。
2> 或(||或则|):同假为假,其它都为真。
3> 非(!):非真即假。
&&与&的区别:&&也叫短路与,与要求前后几个表达式的内容都是true的时候最终结果才是true,如果使用短路与,则只要第一个结果是false,他就不会去判断&&后面的内容了,而&即使知道了第一个表达式结果为false他也要去判断后面表达式的结果; ||(短路或)与|的用法也是一样的。
(4) 位移运算符
右移>> 左移<< 无符号右移>>> 位与& 位或| 非~ 异或^
① 异或^:相同为假,不同为真
异或的有一个特点就是一个数值异或同一个数两次得到的还是自己,所以异或大多应用在文件加密上。
② <<左移:表示一个数值往左边移动,高位舍弃,低位补0,例:
3<<2—>3*2^2= 12
0011<<2 —>1100
③ >>右移:表示一个数值往右边移动,高位原来是什么就用什么补
3>>1—>3/2^1=1
0011—>0001
④ >>>:无符号右移,与右移不同之处在于高位用0补齐
⑤ &位与:与逻辑运算中的与不同,是用来计算数值的,特点与逻辑与一样:同真为真
⑥ |位或:运算数值,同假才假
⑦ ~反转:取反
⑧ ^相同为假,不同为真。
位运算符在java中的应用我感觉相对来说是比较少的,在嵌入式的学习中,当我们使用寄存器时,位运算符的使用就像呼吸一样平常。
(5)三元运算符
表现形式:
(条件表达式)?表达式1:表达式2;
如果条件为true,输入表达式1;如果为false,输出表达式2
例:
int a = 1,b;
b=(a<100)?3:5;
三元表达式类同与if…else语句,不过简化了一下书写,但是三元运算符一定要有结果,这是他的局限性。
(6)赋值运算符
=、+=、-=、*=、/=
注意“+=、-=、*=、/=”是一次运算,有点类似于++;他们虽然看似是两个运算符,但是却是一个运算,他们表示把左右两边的值计算后再赋给左边 。例:
short s = 3;
s+=4;
s的值为7;
如果我们写成s=s+4;虽然看起来+=做的也是这个,但是编译器会给我们报错,因为4是int型,可能损失精度,这就是+=需要注意的地方,他会在底层做一个强制转换动作。
6.流程控制语句
(1) 判断结构:
利用if…else语句
if(条件表达式){执行语句}
if(条件表达式){执行语句}else{执行语句}
if(条件表达式){执行语句}else if(条件表达式){执行语句}…else{执行语句}
(2) 选择结构
Switch语句:
Switch(表达式)
{
执行语句;
break;
case 值2:
执行语句;
break;
…..
default:
执行语句;
break;
}
注意点:case后的值只能是byte、int、long、char型的,default一定要执行的,而且是最后执行的,多用于关闭资源或者数据库。
(3) 循环结构
① while语句
while(条件表达式)
{
}
② do while 语句
do
{
执行语句;
}while(条件表达式);
与while语句的区别在于无论条件是否满足,都会执行一次语句。
③ for语句
for(初始化表达式;循环表达式;循环后表达式)
{
执行语句;
}
for语句与while语句的区别主要在于for循环以内定义变量在循环结束后就在内存中释放了,而while语句在外部定义变量,循环结束后还可以继续使用;for语句的无限循环形式:for(;;),while 语句的无线循环形式:while(true)
④ continue:结束本次循环继续下一次的循环
continue只能作用于循环结构,如果continue单独存在时,他的下面不能有任何语句,因为执行不到。
7.数组
(1)定义数组
① :元素类型[] 名字 = new 元素类型[元素个数或者叫数组长度];
int[] arr = new int[3];
② :元素类型[] 名字 = new 元素类型[元素个数或者叫数组长度];
int[] arr = newint[]{1,2,3};
这种定义格式不允许[]里面再有值
int[] arr = {1,2,3};
(2) 二维数组
二维数组的定义格式为:
数组类型[] []数组名 = new 数组类型[一位数组的个数][二维数组长度];
例:int [][] arrs = new int[3][];
int[][] arrs ={{1,2,3},{4,5,6},{1,2,4}};
二维数组可以理解成用来存放数组的数组,注意就是定义的时候不允许高维长度没初始化,就给低维数组初始化:int[][] arrs =new int[][3];这是错误的。
注意点:数组在初始化时要指定长度,就是length,这个长度一旦确定就不可更改
(3)数组的排序和查找
数组的排序常用的有两种:冒泡排序和选择排序,而查找我们重点说一说二分查找。
public class Demo {
public static void main(String[] args) {
int[]arr = {2,1,5,7,4,3,1,9,0,6};
/*选择排序法:
* 第一个角标位上的元素依次和所有的元素比较,获取到最值,然后剔除最值,让剩下的
* 元素继续比较进行排序,外循环定义比较次数,当剩下一个元素时就不用比较了,因为
* 他已经和前面所有的元素比较过了,所以减一,内循环定义第i个角标和后面的所以角标比
* 所以不用减一
* */
for(int i = 0;i<arr.length-1;i++)
{
for(int j = i+1;j<arr.length;j++)
{
if(arr[j]>arr[i])
{
int num = arr[i];
arr[i] = arr[j];
arr[j] = num;
}
}
}
System.out.println("选择排序法降序排列:");
for(int x= 0;x<arr.length;x++)
{
System.out.print(arr[x]);
}
System.out.println();
/*
* 冒泡排序法:
*相邻两个元素进行比较,比到最后获得最值,然后剔除这个最值,剩下的元素再进行
*比较,依次类推,进行排序,外循环定义比较的次数,n个值比较n-1次就获得了最值,
*因为最后一位已经和前一位比完了所以长度减一,内循环定义谁和谁比,长度减一是因为
*不让角标越界,减i是因为剔除每一次的最值
* */
for(int i = 0;i<arr.length-1;i++)
{
for(int j = 0;j<arr.length-i-1;j++)
{
if(arr[j]>arr[j+1])
{
int num = arr[j+1];
arr[j+1] = arr[j];
arr[j] = num;
}
}
}
System.out.println("冒泡排序法升序排列:");
for(int x= 0;x<arr.length;x++)
{
System.out.print(arr[x]);
}
System.out.println();
/*
* 二分查找法
* 在一个有序数组中找到我们需要的数值角标,为了提高效率,我们把这个数组
* 折半,看中间值和所需数值谁大谁小,由此来缩小搜索范围
* */
//定义最大值、最小值、中间值
int mid,max,min;
int key = 5;
max = arr.length-1;
min = 0;
while(true)
{
//每次都要计算中间值,所以要写在循环里面
mid = (max+min)/2;
//如果中间值小于所需值,最小值变为中间值加一
if(arr[mid]<key)
{
min = mid+1;
}
//如果中间值大于所需值,最大值变为中间值减一
if(arr[mid]>key)
{
max = mid-1;
}
//如果查到最后最大值小于了最小值,那么证明数组中不存在该数值
if(arr[max]<arr[min])
{
break;
}
if(arr[mid]==key)
break;
}
System.out.println("5的角标位是:"+mid);
}
}
/*
* 打印:
* 选择排序法降序排列:
9765432110
冒泡排序法升序排列:
0112345679
5的角标位是:6
* */