JAVA基础复习

[[Java 基础知识]]

考试月忙着复习计算机病毒,网络攻防,协议分析,密码学,还有实训.
一个月没接触JAVA,都快忘光了.
之前买的SpringBoot的书,太多Spring的annotation没学过,看得很难受.
所以暑假买了本SSM的书,从Spring->SpringMVC->SpringBoot一步步学起.
然后,看书之前,先把Java和Java Web的基础内容复习一下.

Hello World

首先,从最简单的hello world来看Java的基础语法和编译执行过程.

package com.company;  
  
public class Main {  
  
    public static void main(String[] args) {  
       System.out.println("Hello World!");  
    }  
}

第一句的package com.company; ,就是声明当前java文件所在的包,类似于C/C++里的library,Python里的package.
不过其他语言都只通过文件夹和路径,来限定一个package的范围.
Java在每个源文件头部,都显示地做了声明.

接下来是我们的类声明和主函数声明定义.
Java是一门彻头彻尾的面向对象语言,通过类和方法来组织代码,就像面向过程的C,用函数来组织代码一样.
有了类和对象,这层更高级的抽象,为代码复用和更高级的设计模式奠定了基础.

第二句public class Main,类的定义,由三部分组成访问修饰符 class 类名 {...}
class是声明类的关键字,类名就是这个类的名字,都好理解.
访问修饰符呢,得解释一下.
Java中有很多修饰符,主要分为两大类

  • 访问修饰符
  • 非访问修饰符

访问修饰符,顾名思义,就是用来控制 类,变量,方法和构造函数 访问权限的修饰符,有如下四类:

  • default(默认,缺省):同一包内可见,不使用任何修饰符.可用于类,接口,变量,方法.
  • private:同一类内可见.可用于变量,方法.=>不能修饰类,类外不可见
  • public:对所有类可见.可用于类,接口,变量,方法.
  • protected:对同一包内的类和所有子类可见.可用于变量,方法.=>不能修饰类

非访问控制符,包括static,fianl,abstract,synchronized,volatile等等,之后用到再逐一介绍.
详见参考资料.

第三句public static void main(String[] args)

这些关键字依次是 访问修饰符,static关键字,返回类型,方法名,参数类型和参数名

  • public访问修饰符,表示该函数对所有类可见.
  • static关键字表示该函数为静态函数,程序运行时便会载入内存.(详见参考资料)
  • void返回类型,表示返回null
  • main为方法名,主函数的意思
  • String[]表示参数类型为字符串数组类型
  • args为参数名

System.out.println("Hello World!");则是调用Java类库的println()函数输出字符串Hello World!
具体Java类库包含哪些package,以及具体功能详见参考资料.

解析完源码后,我们就可以进行编译执行了.
Gif演示

在命令行中输入javac HelloWorld.java将Java源程序(.java)编译成字节码程序(.class)
接着输入java HelloWorld解析执行字节码程序

如图所示,和C/C++这种编译型程序比起来,Java程序多了通过解释器进行解释执行的过程.
这使得Java程序效率较C/C++低,但是也获得了跨平台的优势(在Windows上开发的程序,能够直接在Linux服务器上正常的运行).
同时因为Java程序有编译成字节码,而不是像Python一样完全依靠解析,所以也有不错的性能.
就我认为,综合来说,Java在性能,可移植和开发效率性达成了一个比较好的平衡,非常适合商业软件的开发.

2021年7月8日20:17:47:上面helloworld的例子,把基本的class,package,method,paramater,modifier都做了介绍.
Java基础语法还包括variable,array,enumeration,interface,loop/conditional statement,Java API,exception handling,OOP...
接下来,将逐一过一遍.

类和对象

  • Employee.java
public class Employee {  
    static int number=0;  
    String name;  
    String designation;  
    int age;  
    double salary;  
  
    public Employee(String name){  
        this.name = name;  
        number+=1;  
    }  
    public void setAge(int age){  
        this.age = age;  
    }  
    public void setSalary(double salary){  
        this.salary=salary;  
    }  
  
    public void setDesignation(String designation){  
        this.designation=designation;  
    }  
    public void printEmployee(){  
        System.out.println("name:"+this.name);  
        System.out.println("age:"+this.age);  
        System.out.println("designation:"+this.designation);  
        System.out.println("salary:"+this.salary);  
    }  
}
  • Main.java
public class Main {  
  
    public static void main(String[] args) {  
       Employee emp1 = new Employee("Dou");  
       Employee emp2 = new Employee("Smith");  
       System.out.println(Employee.number);  
  
       emp1.setAge(18);  
       emp1.setSalary(10086.11);  
       emp1.setDesignation("CEO");  
       emp1.printEmployee();  
    }  
}

如上这段代码,演示了类和对象中一些常用的概念.

  • 一个类中的三种变量:
    • 局部变量:method,constructor中的变量.
    • 成员变量:定义在类中的,method外的变量,如name,designation,age,salary
    • 类变量:类中,method外,的static类型变量,如上述的number
  • 构造函数:函数名与类名相同的函数public Employee(String name),多个构造函数可重载.
  • 创建一个对象的三个过程
    • 声明:声明一个对象的名词和类型Employee emp1
    • 实例化:使用关键字new来创建一个对象Employee emp1 = new Employee
    • 初始化:使用new创建对象时,会调用构造方法初始化对象Employee emp1 = new Employee("Dou");
  • 访问实例变量和方法
    • 通过已创建的对象来访问成员变量和方法emp1.setAge(18); emp1.printEmployee();
  • 源文件声明规则
    • 一个源文件只能有一个public类
    • 源文件名应该和public类的类名保持一致

基本数据类型

  • 两大类数据类型
    • 内置数据类型
      • 四个整数型
        • byte
          • 8位 有符号 二进制补码表示的整数
          • 取值范围:-128(-27)~127(27-1)
          • 默认值:0
        • short
          • 16位 有符号 二进制补码表示的整数
          • 取值范围:-32768(-215)~32767(215-1)
        • int
          • 32位 有符号 二进制补码表示的整数
          • 取值范围:-2147483648(-231)~2147483647(231-1)
        • long
          • 64位 有符号 二进制补码表示的整数
          • 取值范围:-9223372036854775808(-263)~9223372036854775803(263-1)
          • 一般用在比较大整数的系统上
          • 默认值0L
      • 两个浮点型
        • float
          • 单精度 32位 符合IEEE 754标准的浮点数
          • 默认值:0.0f
        • double
          • 双精度 64位 符合IEEE 754标准的浮点数
          • 默认值:0.0d
      • 字符类型
        • char
          • 16位 Unicode字符
          • 默认值: 'u0000'
      • 布尔型
        • boolean
          • true/false
          • 默认值:false
    • 引用数据类型
      • 类似于C++中的指针,指向一个对象,指向对象的变量是引用变量
      • 对象,数组都是引用数据类型
      • 默认值为null
  • 常量
    • 程序运行时不能修改
    • final进行修饰,声明方式与变量相似
      • final double Pi = 3.1415926;
    • 0开头表示八进制,0x开头表示十六进制
      • int octal = 0144;
      • int hexa = 0x64;
  • 类型转化
    • 自动类型转换
      • 转换前数据类型位数要低于转换后数据类型位数
        • byte,short,char—> int —> long—> float —> double
    • 强制类型转换
      • 可以把容量大的类型转成容量小的类型
      • 转换过程可能导致溢出或者精度损失
        • int i = 128;
        • byte b = (byte)i;
        • byte类型最大值为127,所以该转换会导致溢出

变量类型

  • 变量声明格式
    • type identifier [= value][, identifier [= value]...];
      • type是Java数据类型
      • identifier是标识符/变量名
      • 中间可以用逗号隔开,同时声明多个同类型变量
  • 变量类型
    • 类变量/静态变量
      • 独立于方法外的变量,用static修饰
      • 无论创建了多少个对象,类只有类变量一份拷贝
      • 除了被声明为常数外,很少使用
      • 在第一次访问时创建,程序结束时销毁
      • 有默认值
      • 可通过ClassName.VariableName的方式访问
      • 声明为public static final类型时,建议变量名使用大写字幕.
        • 如果不是public,final类型,命名方式与实例变量,局部变量相同
    • 实例变量
      • 方法外,没有static修饰的变量
      • 在对象实例化后创建,对象销毁时销毁
      • 至少被一个方法调用
      • 访问修饰符可修饰实例变量
      • 对类中方法可见=>一般把实例变量设为私有,再通过访问修饰符使其对子类可见
      • 有默认值 0,nul,etc
      • 可以通过变量名访问=>但在静态方法/其他类中,应该用完全限定名ObjectReference.VariableName
    • 局部变量
      • 类的方法中的变量
      • 方法执行时创建,完成后销毁
      • 访问修饰符不能用于局部变量
      • 仅在声明的方法内可见
      • 在栈上分配
      • 无默认值,必须手动初始化后才可使用
  • 例子
    	public class Variable{
    		static int classVariable = 0; 
    		String instanceVariable = "hello world"; 
    		public void method(){
    			int localVariable = 0; 
    		}
    	}
    

修饰符

  • 访问修饰符
    • 用来控制类,变量,方法的访问控制权限的修饰符.
    • default=>同package内可见,不用修饰符
    • private=>同class内可见(不能修饰外部类)
      • 私有访问类型的变量只能通过类中公共的getter方法被外部类访问
    • public=>对所有class可见
      • interface里的变量都隐式声明为public static fianl,方法为public
    • protected=>同package内的所有subclass可见(不能修饰外部类)
      • 如果subclass和superclass不在同一个package=>可以继承superclass的,protected方法,但不能直接访问
  • 非访问修饰符
    • 用于实现其他功能的修饰符
    • static
      • 静态变量/类变量:
        • static修饰,独立于对象的静态变量.
        • 无论类实例化多少次,只有一份拷贝.
      • 静态方法:
        • static修饰,独立于类的方法.
        • 静态方法不能使用非静态变量.
        • 静态方法从参数表得到数据,然后计算.
    • final
      • final变量
        • 变量赋值后不能被修改
        • 常和static一起用来创建常量
      • final方法
        • 可被子类继承,但不能被子类重写=>防止方法内容被修改
      • final类
        • 不能被继承
    • abstract
      • 抽象方法
        • 没有任何实现的方法=>具体实现由子类提供
          • 任何继承抽象类的子类必须实现父类的所有抽象方法,除非子类也是抽象类
        • 不能被声明成static,final
      • 抽象类
        • 不能实例化对象
        • 不能同时被abstract和final修饰
        • 抽象类可以不包含抽象方法,但是如果一个类含抽象方法,就必须声明为抽象类=>否则编译错误
    • synchronized
      • 声明方法同一时间只能被一个线程访问
    • volatile
      • 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值.且该值发生变化时,会强制要求线程将变化值写回共享内存=>任何时刻,两个不同线程总是看到某个成员变量的同一个值

运算符

  • 算术运算符
    • +
    • -
    • *
    • /
    • %
    • ++
    • --
  • 关系运算符
    • ==
    • !=
    • >
    • <
    • >=
    • <=
  • 位运算符
    • & =>and
    • | =>or
    • ^ =>xor
    • ~ =>not
    • <<
    • >> =>按位右移
    • >>> =>按位右移,补0
  • 逻辑运算符
    • &&
    • ||
    • !
  • 赋值运算符
    • =
    • +=
    • -=
    • *=
    • /=
    • (%)= =>A%=B 等价于 A=A%B
    • <<=
    • >>=
    • &=
    • ^=
    • |=
  • 其他运算符
    • 三目运算符
      • variable x = (expression) ? value if true : value if false
    • instanceof
      • 检查实例是否为指定类型(数据类型/类/接口)
      • ( Object reference variable ) instanceof (class/interface type)

循环结构

  • while循环
while( 布尔表达式 ) {
	//循环内容 
}
  • do...while循环
    • 先做一遍,在看是否满足循环条件
do {
	//代码语句 
}while(布尔表达式);
  • for循环
for(初始化; 布尔表达式; 更新) { 
	//代码语句 
}
  • 增强 for 循环
    • 主要用于遍历数组
for(声明语句 : 表达式) { 
	//代码句子 
}

声明语句=>声明局部变量,类型与其后数组类型匹配.
表达式=>要访问的数组名or返回值为数组的方法

  • continue和break
    • break
      • 跳出本层循环
    • continue
      • 跳过本次循环=>判断条件是否满足,进行下一次循环

条件语句

  • if-else
if(布尔表达式){
	//如果布尔表达式的值为true 
}else if(布尔表达式 2){
	//如果布尔表达式 2的值为true执行代码 
}else{
	//如果以上布尔表达式都不为true执行代码
}
  • switch-case
switch(expression){
	case value : 
		//语句 
		break; //可选 
	case value : 
		//语句 
		break; //可选 
	default : //可选 
		//语句 
}

switch语句中的变量可以是byte,short,int,char,String(Java SE7)

Number&Math类

  • WrapperClass
    • 在开发中,我们常常要使用对象,而不是内置数据类型,所以Java为每个内置数据类型都提供了对应的WrapperClass

    • boolean=>Boolean

    • byte=>Byte

    • short=>Short

    • int=>Integer

    • long=>Long

    • char=>Character

    • float=>Float

    • double=>Double

      • Integer,Byte..都是抽象类java.lang.Number的子类
      • 编译器可以把内置类型当做对象使用(装箱),也可以把一个对象拆箱为内置类型
        • 比如让内置类型变量和包装类对象相加
      • Number类常用方法
        • xxxValue=>将Number对象转化为xxx数据类型的值并返回
        • compareTo=>将Number对象与参数比较
        • equals=>判断Number对象是否与参数值相等
        • valueOf=>返回一个Number对象指定的内置数据类型
        • toString=>以字符串形式返回
  • Math类
    • 包含了执行基本数学运算的属性和方法
    • Math的方法都被定义为static,通过Math类可以直接在主函数中调用
    • parseInt=>将字符串解析为int类型
    • abs=>返回参数的绝对值
    • ceil=>返回大等于参数的最小整数,类型为double
    • floor=>返回小等于参数的最大整数
    • rint=>返回与参数最接近的整数
    • round=>四舍五入
    • min=>返回两个参数最小值
    • max=>返回两个参数最大值
    • exp=>返回自然数底数e的参数次方
    • log=>返回参数的自然数底数的对数值
    • pow=>返回第一个参数的第二参数次方
    • sqrt=>算术平方根
    • sin=>求正弦值
    • cos,tan,asin,acos,atan
    • atan2=>将笛卡尔坐标转化为极坐标,并返回极坐标角度
    • toDegrees=>将参数转化为角度
    • toRadians=>将角度转化为弧度
    • random=>生成随机数

Character类

  • character类用于对单个字符进行操作
  • character类在对象中包装了一个基本数据类型char的值
  • 为什么不用内置数据类型char,而是使用character类?
    • character类提供了一系列操作字符的方法
  • 和Number类一样,character类和char内置数据类型可以互相转换(装箱,拆箱)
  • 方法
    • isLetter()
    • isDigit()
    • isWhitespace()
    • isUpperCase()
    • isLowerCase()
    • toUpperCase()
    • toLowerCase()
    • toString()
  • 转义字符
    • \t 制表符,插入一个Tab
    • \b 插入一个人后退键
    • \n 换行
    • \r 插入回车
    • \f 插入换页符
    • \' 单引号
    • \" 双引号
    • \\ 反斜杠

String类

  • 创建字符串
    • 直接赋字符串常量 String s1="iamnotastring"
      • 字符串存储在公共池里,多个变量值相同,则指向同一个存储单元
    • 构造函数 String s2= new String("iamnotastring")
      • 存储在堆上,值相同也是不同存储单元
    • 还可以用char[]来初始化字符串
  • String类不可变,一旦创建完对象,值就无法改变
    • 如果需要对字符串做多次修改,应该选择使用StringBuffer&StringBuilder类
  • 通过length()方法获取长度
  • 通过concat()方法,或者.,+操作符,连接字符串
  • 通过String类的静态方法format(),可以创建一个格式化的String对象
  • String类 更多方法

StringBuffer & StringBuilder 类

  • 上图可见StringBuffer,StringBuffer,String三个类的关系
    • String类实现了charsequence,但没有实现appendable接口,所以是不可修改的字符序列
    • StringBuilder和StringBuffer都是AbstractStringBuilder(实现了appendable接口)的子类,所以是能够进行修改的字符序列
      • StringBuffer在使用时对对象本身进行操作,不产生新对象=>需要对字符串修改时推荐使用StringBuffer
      • StringBuilder在Java5被提出,和StringBuffer最大的区别在于线程不安全(不能同步访问),但是也因此有速度优势,所以多数情况下还是建议使用StringBuilder类
  • StringBuffer类 方法
    • append
    • reverse
    • delete
    • insert
    • replace
    • capacity
    • charAt(int index)
    • ensureCapacity(int minimumCapacity)
    • getChars(int srcBegin,int srcEnd,char[] dst,int dstBegin)
    • indexOf(String str)
    • lastIndexOf
    • length
    • setCharAt
    • subSequence
    • subString
    • toString

数组

  • 用来存储固定大小的同类型元素
  • 声明
    • 推荐方法 dataType[] arrayRefVar;
    • 效果相同,不推荐=>为方便C/C++程序员看懂而设计 dataType arrayRefVar[];
  • 创建数组
    • arrayRefVar = new dataType[arraySize];
      • 使用dataType[arraySize]创建了一个数组
      • 把新创建的数组赋值给arrayRefVar
    • 创建和声明2 in 1 dataType[] arrayRefVar = new dataType[arraySize];
    • 声明,创建,初始化3 in 1dataType[] arrayRefVar = {value0,value1,...};
  • 处理数组
    • 数组元素类型和大小都是固定的=>一般用For-Each循环遍历处理
    for(type element:array){
    	...
    }
    
  • 数组作为参数
    • public static void printArray(int[] array){...}
  • 数组作为返回值
    • public static int[] reverse(int[] list) {...}
  • 多维数组
    • 声明定义type[][] typeName = new type[typeLength1][typeLength2];
    • 引用arrayName[index1][index2]
  • Arrays类
    • java.util.Arrays类提供了很多静态方法来方便地操作数组
    • 给数组赋值=>public static void fill(int[] a, int val)=>将指定的 int 值分配给指定 int 型数组指定范围中的每个元素
    • 对数组排序=>public static void sort(Object[] a)=>对指定对象数组根据其元素的自然顺序进行升序排列
    • 比较数组=>public static boolean equals(long[] a, long[] a2)=>如果两个指定的 long 型数组彼此_相等,则返回 true
    • 查找数组元素=>public static int binarySearch(Object[] a, Object key)=>用二分查找算法在给定数组中搜索给定值的对象(Byte,Int,double等)。数组在调用前必须排序好的。如果查找值包含在数组中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。

时间日期

  • java.util包提供了Date类来封装当前的日期和时间
  • 构造函数
    • Date()自动获取当前日期和时间来初始化对象
    • Date(long millisec)通过1970年1月1日至今的毫秒数来初始化对象
  • 方法
    • boolean after(Date date)=>若当调用此方法的Date对象在指定日期之后返回true,否则返回false
    • boolean before(Date date)=>若当调用此方法的Date对象在指定日期之前返回true,否则返回false
    • Object clone()=>返回此对象的副本
    • int compareTo(Date date)=>比较当调用此方法的Date对象和指定日期。两者相等时候返回0。调用对象在指定日期之前则返回负数。调用对象在指定日期之后则返回正数。
    • int compareTo(Object obj)=>若obj是Date类型则操作等同于compareTo(Date) 。否则它抛出ClassCastException。
    • boolean equals(Object date)=>当调用此方法的Date对象和指定日期相等时候返回true,否则返回false。
    • long getTime()=>返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
    • int hashCode()=>返回此对象的哈希码值
    • void setTime(long time)=>用自1970年1月1日00:00:00 GMT以后time毫秒数设置时间和日期。
    • String toString()=>把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy
      • dow(DayOfWeek) 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。
  • 格式化时间
    • 使用 SimpleDateFormat 格式化日期
    Date dNow = new Date( ); 
    SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss"); 		
    System.out.println("当前时间为: " + ft.format(dNow));
    
    • 也可以用printf输出格式化时间
    • SimpleDateFormat还可以使用parse()方法解析提取字符串中的时间
  • 休眠
    • Thread.sleep(3*1000);使当前线程休眠3秒
  • Calendar类
    • 可以获取日期的特定部分(小时,日,分钟)
    • 功能比Date类强大,也更复杂

正则表达式

  • 定义了字符串的模式,可以用来搜索,编辑,处理文本
  • java.util.regex提供了以下三个类
    • Pattern
      • pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。
    • Matcher
      • Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。
    • PatternSyntaxExecption
      • PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。
  • 例子
    import java.util.regex.*; 
    class RegexExample1
    { 
    	public static void main(String[] args){ 
    		String content = "I am noob " + "from runoob.com."; 
    		String pattern = ".*runoob.*"; 
    		boolean isMatch = Pattern.matches(pattern, content); 
    		System.out.println("字符串中是否包含了 'runoob' 子字符串? " + isMatch); 
    	} 
    }
    
  • 正则表达式要用的时候再看,不然看了也是忘

复习完上面这些基础内容
剩下的输入输出流,文件操作,OOP,异常处理
可以看我之前看翁恺老师课程做的笔记
Java 基础知识 - rpish - 博客园 (cnblogs.com)

参考资料

posted @ 2021-07-08 00:52  rpish  阅读(140)  评论(0编辑  收藏  举报