Java基础

发布时间 2023-05-31 15:05:10作者: Roy-Huang

Java基础

java简介

Java是一门高级的面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。

java特性和优势

  • 简单性
  • 面向对象
  • 可移植性
  • 高性能
  • 分布式
  • 动态性
  • 多线程
  • 安全性
  • 健壮性

Java三大版本

  1. JavaSE: 标准版(桌面程序,控制台开发...)
  2. JavaME: 嵌入式开发(手机,小家电...)(基本已经去世,没人用了)
  3. JavaEE: 企业级开发(web端,服务器开发...)

JDK、JRE、JVM

  1. JDK:Java Development Kit
  2. JRE:Java Runtime Environment
  3. JVM: JAVA Virtual Machine
    从上到下,包含关系

Java环境安装

卸载Java

  1. 删除java的安装目录
  2. 删除JAVA_HOME
  3. 删除Path环境变量中Java变量
  4. cmd输入java -version

安装JDK

  1. 官网下载对应版本Java安装包
  2. 安装后记住安装路径
  3. 配置环境变量
    1. 我的电脑->右键->属性
    2. 系统环境变量->JAVA_HOME->java安装地址
    3. 配置Path变量%JAVA_HOME%\jre\bin%和JAVA_HOME%\jre\bin
  4. 测试安装是否成功:cmd输入java -version检查

Java程序运行机制

java源程序(*.java文件)->Java编译器->字节码文件(*.class)->类装载器->字节码校验器->解释器->操作系统平台

1、注释、标识符、关键字

注释

  1. 单行注释 //单行
  2. 多行注释 /*多行*/
  3. 文档注释 /**文档*/

标识符和关键字

Java所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。

关键字

  • 所有的标识符都应该以字母(A-Z或者a-z) 、美元符($)或者下划线(_)开始
  • 首字符之后可以是字母(A-Z或者a-z) 、美元符($)、下划线(_)或数字的任何字符组合
  • 不能使用关键字作为变量名或方法名。
  • 标识符是大小写敏感
  • 不建议使用中文命名和拼音

2、数据类型

Java是强类型语言:要求变量的使用严格符合规定,所有变量都必须先定义后才能使用。

Java的数据类型分为两大类

  • 基本类型

    1. 数值型
      1. 整数型
        1. byte
        2. short
        3. int
        4. long(数字后面加L)
      2. 浮点型
        1. float(数字后面加F)
        2. double
    2. boolean型(true和false)(注:和c不同,不能用整数0或者非0表示false和true)
  • 引用类型

    1. 接口
    2. 数组

3、类型转换

运算中,不同类型的数据先转换为同一数据类型(容量最大的类型)再运算。

低容量-------------------------------------高容量

byte,short,char->int->long->float->double

强制转换 (类型)变量名 高->低

自动转换 低->高

注意:

  1. 不能对布尔值进行转换
  2. 不能把对象类型转换为不相干类型
  3. 在把高容量转换到低容量的时候,强制转换
  4. 转换的时候可能存在内存溢出,或者精度问题

4、变量、常量

变量

type varName [=value][{,=value}];
//数据类型 变量名=值,可以用逗号隔开来声明多个同类型变量

◆注意事项:

  • 每个变量都有类型,类型可以是基本类型,也可以是引用类型。
  • 变量名必须是合法的标识符。
  • 变量声明是一条完整的语句,因此每一个声明都必须以分号结束

变量作用域

  1. 类变量:static 变量名
  2. 实例变量:从属于对象;如果不自行初始化,这个类型默认值为0,0.0,布尔值false,除了基本类型,其他都为null
  3. 局部变量:必须声明和初始化值

常量

常量(Constant):初始化(initialize)后不能再改变值!不会变动的值

final 常量名=值;
例:final double PI=3.14;

常量名一般使用大写字符

变量命名规范

  • 所有变量、方法.类名:见名知意
  • 类成员变量:首字母小写和驼峰原则: monthSalary除了第一个单词以外,后面的单词首字母大写lastname lastName
  • 局部变量:首字母小写和驼峰原则
  • 常量:大写字母和下划线: MAX_VALUE
  • 类名:首字母大写和驼峰原则: Man, GoodMan
  • 方法名:首字母小写和驼峰原则: run(), runRun()

5、运算符

  • 算术运算符:+、-、*、/、%、++、--
  • 赋值运算符:=
  • 关系运算符:>、<、>=、<=、==、!=instanceof(浮点数因为精度问题不建议直接判断相等,建议使用通过两个数差值的精度来比较判断相等)
  • 逻辑运算符:&&、||、!
  • 位运算符:&、|、^、~、>>、<<、>>>
  • 条件运算符:? :
  • 扩展赋值运算符:+=、-=、*=、/=
//字符串连接符 + 如果运算中前面出现了任意字符串,后面的数值会拼接并转换为字符串
int a=10;
int b=20;
System.out.println(" "+a+b);
//输出:1020
System.out.println(a+b+" ");
//输出:30

6、包机制、JavaDoc

包机制

为了更好地组织类,Java提供了包机制,用于区别类名的命名空间

包语句的语法格式 package pkg1[.pkg2[.pkg3]];

  • 一般利用公司域名倒置作为包名

为了能够使用某一个包的成员,我们需要在Java程序中明确导入该包。使用“import”语句可完成此功能
import package1[.package2].(classname|*)

JavaDoc

  • javadoc命令是用来生成自己的API文档
  • 参数信息:
    • @author 作者名
    • @version 版本号
    • @since 指明需要最早使用的jdk版本
    • @param 参数名
    • @return 返回值情况
    • @throws 异常抛出情况

终端生成JavaDoc

javadoc -encoding UTF-8 -charset UTF-8 Doc.java

7、Scanner

我们可以通过Java.util.Scanner包中的Scanner类来获取用户输入

  • 基本语法

Scanner s = new Scanner(system.in);

next()读取字符串,以空格为分隔符或结束符号。

nextLine()读取字符串,以回车为结束符。

nextXxx()接受不同类型数据;Xxx表示其他数据类型。

hasNextXxx判断是否输入了相应类型的数据。

8、顺序结构

  • JAVA的基本结构就是顺序结构,除非特别指明,否之就按照顺序一句一句执行。
  • 顺序结构是最简单的算法结构
  • 语句与语句之间,按从上到下的顺序进行的,它是由若干个一次执行的处理步骤组成的,它是任何一种算法都离不开的一种基本算法结构。

选择结构

if...else...,switch

单选择结构语法

if(布尔表达式){
    //如果不二表达式为true将执行的语句。
}

双选址结构语法

if(布尔表达式){
    //如果布尔表达式为true将执行的语句。
}
else{
    //如果布尔表达式为false将执行的语句。
}

多选择结构else if语法

if(布尔表达式 1){
    //如果布尔表达式 1为true将执行的语句。
}
else if(布尔表达式 2){
    //如果布尔表达式 2为true将执行的语句。
}
else if(布尔表达式 3){
    //如果布尔表达式 3为true将执行的语句。
}
else {
    //如果以上布尔表达式都不为true将执行的语句。
}

多选择结构switch语法

switch case语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。

switch(expression){
    case value1:
        //语句
        break;//可选
        case value2:
        //语句
        break;//可选
        case value3:
        //语句
        break;//可选
        ...
        default://可选
         //语句
}

9、循环结构

避免死循环,少部分需要循环一直执行,比如服务器的请求响应。

while

先判断在执行

while(布尔表达式){
    //循环内容
}

do...while

先执行在判断,至少执行一次循环内容

do {
    //循环内容
} while(布 尔表达式)

for循环

 for(初始化;布尔表达式;迭代){
     //循环内容
 }

增强型

for(声明语句:表达式){
    //代码
}

◆声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。

◆表达式:表达式是要访问的数组名,或者是返回值为数组的方法。

10、break、continue

break:用于强制结束循环,不执行循环中剩余的语句。
continue:用于跳过循环体中尚未执行的语句,直接进入下一次的循环判定。

11、方法

  • Java方法是语句的集合,它们在一起执行一个功能。方法是解决一类问题的步骤的有序组合

  • 方法包含于类或对象中

  • 方法在程序中被创建,在其他地方被引用

  • 设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合。我们设计方法的时候,最好保持方法的原子性,就是一个方法只完成1个功能,这样利于我们后期的扩展。

  • 方法名:首字母小写和驼峰原则: run(), runRun()

方法的定义和调用

  • 修饰符:修饰符,可选,而且可以有多个,告诉编译器如何调用该方法,。定义了该方法的访问类型。
  • 返回值类型: 方法可能会返回值。returnValueType是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType是关键字void。
  • 方法名:是方法的实际名称。方法名和参数列表共同构成方法签名。
  • 参数类型:参数像是-个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
    • 形参:在方法被调用的时用于接受外界输入的数据。
    • 实参:调用方法时实际传给方法的数据。
  • 方法体:方法体包含具体的语句,定义该方法的功能。
修饰符 返回值类型 方法名(参数类型 参数名,...){
    方法体;
    return 返回值;
}

方法的重载

重载就是在一个类中,有相同的函数名称,但形参不同的函数。

方法的重载的规则:

  • 方法名称必须相同。
  • 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)。
  • 方法的返回类型可以相同也可以不相同。
  • 仅仅返回类型不同不足以成为方法的重载。

实现理论:方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。

命令行传递参数

有时候你希望运行一个程序时候再传递给它消息。这要靠传递命令行参数给main()函数实现。

public class Demo03 {
    public static void main(String[] args) {
        for (int i = 0; i <args.length ; i++) {
            System.out.println(args[i]);
        }
    }
}

先通过命令行到包内javac进行编译,再到包外运行。
命令行传参

可变参数(不定项参数)

在方法声明中,在指定参数类型后加一个省略号(...).
一个方法中只能指定一个可变参数,他必须时方法的最后一个参数。任何普通的参数必须在它之前声明。

语法:public void test(int... i)

public class Demo04 {
    public static void main(String[] args) {
        Demo04 demo04 = new Demo04();
        demo04.test(1,2,3);
    }
    public void test(int... i){
        for (int j = 0; j < i.length; j++) {
            System.out.println(i[j]);
        }

    }
}

递归

递归就是自己调用自己。

利用递归可以用简单的程序来解决-些复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。

递归结构包括两个部分:

  • 递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
  • 递归体:什么时候需要调用自身方法。

12、数组

定义

数组是相同类型数据的有序集合。

数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。

其中,每一个数据称作一个数组元素每个数组元素可以通过一个下标来访问它们.

声明和创建

  • 声明
dataType[] arrayRefVar;//首选方法
dataType arrayRefVar[];//效果相同,但不是首选方法
  • 创建
dataType[] arrayRefVar = new dataType[arraySize];

数组的元素时通过索引访问的,数组索引从0开始。

获取数组长度:arrays.length

  • 其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
  • 其元素必须是相同类型,不允许出现混合类型。
  • 数组中的元素可以是任何数据类型,包括基本类型和引用类型。
  • 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,
    数组对象本身是在堆中的。

初始化

  • 静态初始化 int[] a={1,2,3,4,5,6,7,8}
  • 动态初始化
int[] b=new int[10]
a[0]=1;
b[1]=2; 
  • 数组的默认初始化
  • 数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。

多维数组

int a[][]=new int[2][5];

Arrary类

  • 数组的工具类java.util.Arrays
  • 由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作。
  • 查看JDK帮助文档
  • Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而"不用"使用对象采调用(注意:是"不用"而不是"不能")
  • 具有以下常用功能:给数组赋值:通过fill方法。
  • 对数组排序:通过sort方法,按升序。
  • 比较数组:通过equals方法比较数组中元素值是否相等。
  • 查找数组元素: 通过binarySearch方法能对排序好的数组进行二分查找法操作。

稀疏数组

当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。

稀疏数组的处理方式是:

  • 记录数组-共有几行几列,有多少个不同值
  • 把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模
//原数组
0 0 0 22 0
0 11 0 0 0
0 0 0 -6 0
0 0 0 0 0
0 0 0 0 0
    行 列 值
[0] 5  5  3
[1] 0  3  22
[2] 1  1  11
[3] 2  3  -6

代码实现

public static void main(String[] args) {
        //1.创建一个数组
        /*
        0 0 0 22 0
        0 11 0 0 0
        0 0 0 -6 0
        0 0 0 0 0
        0 0 0 0 0
         */
        int[][] array1=new int[5][5];
        array1[0][3]=22;
        array1[1][1]=11;
        array1[2][3]=-6;
        for (int[] a:array1) {
            for (int b:a) {
                System.out.print(b+"\t");
            }
            System.out.println();
        }
        //2.获取有效值个数
        int sum=0;
        for (int[] a:array1) {
            for (int b:a) {
                if (b!=0) sum++;
            }
        }
        //2.转换为稀疏数组
        int[][] array2 = new int[sum + 1][3];
        //数组头排
        array2[0][0]=5;
        array2[0][1]=5;
        array2[0][2]=sum;
        //记录
        int count=0;
        for (int i = 0; i <5 ; i++) {
            for (int j = 0; j < 5; j++) {
                if (array1[i][j]!=0){
                    count++;
                    array2[count][0]=i;
                    array2[count][1]=j;
                    array2[count][2]=array1[i][j];
                }
            }
        }
        //3.输出稀疏数组
        System.out.println("稀疏数组============");
        for (int i = 0; i <array2.length ; i++) {
            System.out.println(array2[i][0]+"\t"+array2[i][1]+"\t"+array2[i][2]);
        }
        System.out.println("还原稀疏数组==========");
        int[][] array3=new int[array2[0][0]][array2[0][1]];
        //记录是从1开始的,因为第一排是数组信息。
        for (int i = 1; i < array2.length; i++) {
            array3[array2[i][0]][array2[i][1]]=array2[i][2];
        }
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                System.out.print(array3[i][j]+"\t");
            }
            System.out.println();
        }
    }