java base - yaokun123/php-wiki GitHub Wiki

Java语言基础

一、关键字

关键字都是小写 例如:class、static、public、void

二、标识符

在程序中自定义的一些名称。

由26个英文字母大小写、数字0-9、符号:_$组成

定义合法的标识符

1、数字不可以开头
2、不可以使用关键字

注意:java中严格区分大小写,在起名字的时候,为了提高阅读性,要尽量有意义。

三、注释

单行注释://
多行注释:/* */
文档注释:/** */    这个注释可以通过java JDK的javadoc命令提取文档注释,生成说明书

注意:源文件的注释不会被编译到字节码文件中

四、常量和变量

常量表示不能改变的数值

变量的概念
   》内存中的一个存储区域
   》该区域有自己的名称(变量名)和类型(数据类型)
   》该区域的数据可以在同一类型范围内不断变化
为什么要定义变量
   》用来不断的存放同一类型的常量,并可以重复使用
使用变量注意
   》变量的作用范围(一对{}之间有效)
   》初始化值
定义变量的格式
   》数据类型 变量名 = 初始化值
java语言是强类型语言,对于每一种数据都定义了明确的具体数据类型,在内存中分配了不同的内存空间
                         |正数类型(byte(1字节)、short(2字节)、int(4字节)、long(8字节))
                   |数值型|
                   |     |浮点类型(float(4字节)、double(8字节))
       |基本数据类型|字符型(char(2字节))
       |           |布尔型(boolean)
数据类型|
       |           |类(class)
       |引用数据类型|接口(interface)
                   |数组([])

注意:正数默认为int,小数默认为double

类型转换

  • 1、自动类型转换(也叫隐式类型转换)
表达式的数据类型自动提升
int x =3;
byte b = 5;
x = x + b;//会对b进行自动类型提升到int
    》所有的byte型、short型、和char的值将会被提升到int
    》如果一个操作数是long型,计算结果就是long型
    》如果一个操作数是float型,计算结果就是float型
    》如果一个操作数是double型,计算结果就是double型
  • 2、强制类型转换(也叫显式类型转换)
byte b =3;
b = (byte)(b + 4);//强制将得出的int结果转换为byte类型

注意:强制转换会失去精度,要谨慎使用

一些陷阱

没有问题的例子:
byte b = 4;//此时的4是int类型,但是编译器在编译的时候会检测是否在byte范围内,如果在就可以正常赋值
b = 3+7;//同上
System.out.println(b);

有陷阱的例子:
byte b = 4;
byte b1 = 3;
byte b2 = 4;
b = b1+b2;//由于此时b1与b2都是变量,所以编译器不能确定其值得范围,会报错的,将类型改为int就可以了。
System.out.println(b);

改正:
int b = 4;
int b1 = 3;
int b2 = 4;
b = b1+b2;//虽然b1与b2都是变量,但是整数的运算范围在int范围内就可以
System.out.println(b);

那么问题来了,如果b1和b2足够大,导致相加之后的值范围超过int的范围怎么办?
int b = 4;
int b1 = Integer.MAX_VALUE;//int范围的最大值
int b2 = 4;
b = b1+b2;//此时的值已经超过了int的最大范围,会丢失精度变成负数
System.out.println(b);

五、运算符

  • 1、算术运算符
加(+)、 减(-)、 乘(*)、 除(/)、 取模(%)、连接符(+)、自增(++)、自减(--)
连接符:任何数据和字符串相加都是拼接

eg:
int x = 6370;
x = x/1000 * 1000;//这是java语言的独特运算特点,两个整数相除,结果还是整数,舍弃小数位
System.out.println(x);//6000

int a = 3,b;
b = a++;//后加加的优先级较低,所以先赋值再自增
System.out.println("a="+a+",b="+b);//a=4,b=3

int a = 3,b;
b = ++a;//前加加的优先级较高,所以先自增再赋值
System.out.println("a="+a+",b="+b);//a=4,b=4
  • 2、赋值运算符
= 、+= 、*= 、/= 、%=

eg:
short s = 3;
//下面这这两条语句有什么不同
s += 4;//编译通过。这个是一次赋值运算,同上原理一样,在底层做了自动转换(是赋值运算具备的特点)。
s = s + 4;//编译失败。这个是两次运算,s是一个变量,右边的值不确定,所以不能通过编译。
System.out.println(s);
  • 3、比较运算符
大于(>)、大于等于(>=)、小于(<)、小于等于(<=)、等等于(==)、不等于(!=)、instanceof(检查是否是类的对象)

注意1:比较运算符运算结果是布尔值(true/false)
注意2:比较运算符“==”不能误写成“=”
  • 4、逻辑运算符
与(&/AND)、或(|/OR)、异或(^/XOR)、非(!/Not)、短路与(&&/AND)、短路或(||/OR)
  • 5、位运算符
左移(<<)、右移(>>)、无符号右移(>>>)、与运算(&)、或运算(|)、异或运算(^)、反码(~)

注意:这里说的为代值二进制位/比特位

一个数异或同一个数两次得到的结果还是这个数(6^3^3=6),利用这个特性可以搞一个数据加密
左移几位就是该数据乘以2的几次方
右移几位就是该数据除以2的几次方

练习:
1、最有效的方式算出2乘以8等于几?
答案:2<<3
2、 对两个整数变量的值进行互换(不需要第三方变量)。
答案:
int a = 3,b = 5;
System.out.println("a="+a+",b="+b);//a = 3,b = 5;
//方法一:这种方式不要用,如果两个整数的数值过大,会超出int范围,会强制转换,数据会变化。
a = a + b;
b = a - b;
a = a - b;
System.out.println("a="+a+",b="+b);//a = 5,b = 3;

//方法二:
a = a ^ b;
b= a ^ b;
a = a ^ b;
System.out.println("a="+a+",b="+b);//a = 5,b = 3;
  • 6、三元运算符
(条件表达式)? 表达式1 : 表达式2
如果条件为true,运算后的结果是表达式1
如果条件为false,运算后的结果是表达式2

六、语句

程序流程控制

  • 1、判断结构
if语句三种格式:
格式一:
if(条件表达式){
    执行语句;
}

格式二:
if(){
    执行语句;
}else{
    执行语句;
}

格式三:
if(条件表达式){
    执行语句;
}else if(条件表达式){
    执行语句;
}else{
    执行语句;
}

局部代码块 局部代码块可以定义局部变量的声明周期。

public static void main(String[] args){
    
    {//这就是局部代码块
         int m = 89;//在局部代码块中定义的变量,作用于是局部的
         System.out.println("hello world" + "...." + m);
    }//到这里变量m在内存中已经被释放了
    System.out.println("over" + "...." + m);//编译错误,找不到变量m
}
  • 2、选择结构
switch语句
格式:
switch(表达式){
    case 取值1:
        执行语句;
        break;
    case 取值2:
        执行语句;
        break;
    case 取值3:
        执行语句;
        break;
    default:
        执行语句;
        break;
}
  • 3、循环结构
代表语句:while、do while、for

while语句格式:
while(条件表达式){
    执行语句;
}

do while语句格式://特点:条件无论是否满足,循环体至少执行一次。
do{
    执行语句;
}while(条件表达式);

for语句格式:
for(c初始化表达式;循环条件表达式;循环后的操作表达式){
    执行语句(循环体);
}
  • 4、其他流程控制语句
break(跳出):应用于选择结构和循环结构
continue(继续):应用于循环结构

七、函数

  • 1、函数的定义 什么是函数?

函数就是定义在类中具体特定功能的一段独立小程序
函数也称为方法。

函数的格式:
修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2,...){
    执行语句;
    
    return 返回值;
}

返回值类型:函数运行后的结果的数据类型。
参数类型:是形式参数的数据类型。
形式参数:是一个变量,用于存储调用函数是传递给函数的实际参数。
实际参数:传递给实际参数的具体数值。
return:用于结束函数。
返回值:该函数运算后的结果,该结果会返回给调用者。

注意特殊情况:函数功能没有具体的返回值,这是return的后面直接使用分号结束,返回值类型为void。

注意:如果返回值类型是void,那么函数中的return可以省略不写。

  • 2、函数的特点
定义函数可以将功能代码进行封装。
便于对该功能进行复用。
函数只有被调用才会执行。
函数的出现提高了代码的复用性。
对于函数没有具体的返回值的情况,返回值类型用关键字void表示,那么该函数中的return语句如果在最后一行可以省略不写

注意:函数中只能调用函数,不可以在函数内部定义函数。

定义函数时,函数的结果应该返回给调用者,交由调用者处理。

  • 3、函数的内存加载过程

这片内存空间叫做栈。主函数先入栈。

  • 4、函数的重载(overload)
重载的概念:
在同一个类中,允许存在一个以上的同名函数,只要他们的参数个数或者参数类型不同即可。

重载的特点:
与返回值类型无关,只看参数列表。

重载的好处:
方便于阅读,优化了程序设计。

重载示例:
//返回两个整数的和
int add(int a,int b){return a+b';}
//返回三个整数的和
int add(int a,int b,int c){return a+b+c;}
//返回两个小数的和
double add(double a,double b){return a+b;}

注意:如果参数个数,参数类型,函数名都一样的话,编译直接报错

八、数组

  • 1、数组的定义
概念:
同一种类型数据的集合。其实数组就是一个容器。

数组的好处
可以自动给数组中的元素从0开始编号,方便操作这些元素。

格式1:
元素类型[] 数组名 = new 元素类型[元素个数或数组长度]
int[] arr = new int[5]

格式2:元素类型[] 数组名 = new 元素类型[]{元素,元素,....}
int[] arr = new int[]{1,2,3,4}
int[] arr = {1,2,3,4}
  • 2、数组的内存分配及特点
内存的划分:
1、寄存器:给cpu使用的
2、本地方法区:本地系统平台中的内容
3、方法区:
4、栈内存:存储的都是局部变量(凡是定义在方法中的变量)
5、堆内存:存储的是数组和对象(数组其实就是对象),凡是new 建立在堆中。
    特点:
        》每一个实体都有首地址值。
        》堆内存中的每一个变量都有默认初始化值,根据类型不同而不同,整数0、小数0.0或者0.0f、布尔false、char '\u0000'
        》优秀的垃圾回收机制(c需要程序员手动释放)

为什么方法要进栈?因为局部变量都在方法里,方法不进栈,局部变量就不能进栈。

  • 3、数组操作常见问题
问题一:ArrayIndexOutOfBoundsException(执行错误)
当访问到数组中不存在的角标时,就会发生该异常。
int[] arr = new int[3];
System.out.println(arr[3]);

问题二:NUllPointerException
当引用型变量没有任何实体指向时,还在用其操作实体,就会发生该异常
int[] arr = new int[3];
arr = null;
System.out.println(arr[3]);

问题三:直接将数组名打印出来
int[] arr = new int[3];
System.out.println(arr);
  • 4、数组常见操作 对数组操作最基本的动作就是存和取

核心思想:就是对角标的操作

1、获取数组的长度:数组的属性arr.length
2、获取最值(最大值,最小值)
public static int getMax(int[] arr){
    int maxElement = arr[0];
    for(int x = 1;x<arr.length;x++){
        if(arr[x]>maxElement ){
            maxElement  = arr[x];
        }
    }
    return maxElement;
}
3、排序(选择排序,冒泡排序,插入排序)
选择排序:
public static void selectSort(int[] arr){
    for(int x = 0;x<arr.length-1;x++){
        for(int y = x+1;y<arr.length;y++){
            if(arr[x]>arr[y]){
                int temp = arr[x];
                arr[x] = arr[y];
                arr[y] = temp;
            }
        }
    }
}
冒泡排序:
public static void bubbleSort(int[] arr){
    for(int x = 0;x<arr.length-1;x++){
        for(int y = 0;y<arr.length-1-x;y++){
            if(arr[y]>arr[y+1]){
                int temp = arr[y];
                arr[y] = arr[y+1];
                arr[y+1] = temp;
            }
        }
    }
}
4、折半查找(二分查找)
public static int halfSearch(int[] arr,int key){
    int max,min,mid;
    min = 0;
    max = arr.length-1;
    mid = (max+min)/2;

    while(arr[mid]!=key){
        if(key>arr[mid]){
            min = mid + 1;
        }else if(key < arr[mid]){
            max = mid -1;
        }

        if(max <min){
            return -1;
        }
    }
    return mid;
}

  • 5、数组中的数组 二维数组
格式一:
int[][] arr = new int[3][2];

格式二:
int[][] arr = new int[3][];

格式三:
int[][] arr = {{},{},{}}

二维数组的长度就是一维数组的个数。

⚠️ **GitHub.com Fallback** ⚠️