javase基础大全

JavaSE

java的语言特点

  1. 面向对象(贴近人类思维模式,模拟现实世界,解决现实问题)

  2. 简单性(自动内存管理机制、不易造成内存溢出;简化流程处理、语义清晰)

  3. 跨平台(操作系统、服务器)

Java运行机制

一次编写,多次执行

  • JDK :开发工具和类库、包含了jre

  • JRE:运行环境,包含了jvm虚拟机

  • JVM:虚拟机,不同操作系统模拟相同的环境 源文件.java通过虚拟机编译为.class文件

环境变量

变量:系统属性; 变量名----变量值

JAVA_HOME---jdk的根目录, E:\jdk\Java\jdk1.8.0_51

path ----jdk安装目录里的bin;可以任意的路径访问命令; %JAVA_HOME%\bin E:\jdk\Java\jdk1.8.0_51\bin classpath: 类路径;----自从jdk1.5版本后可以不用配;

 .;%JAVA_HOME%\lib;

JDK目录;JDK的bin目录:存放的是exe文件,可称为执行文件;

标识符命名规则

语法规则: 由数字、字母、下划线、$组成; 不能以数字开头;

约定: 见名知义; 类名:一个或多个单词首字母大写;例:Hello、HelloWord 方法/变量:一个或多个单词,第一个字母小写,其它单词字母大写;例: getName name pass 包名:全小写,用点分隔,反向域名;例:com.qf.test 常量:全部大写并且用_分隔多个单词;例:HELLO_WORLD

变量

声明变量 给变量赋值

初始化变量

  • 第一种定义方式:

    类型 变量名=值;

  • 第二种定义方式: 类型 变量名; 变量名=值;

  • 全局变量

定义在类内,方法外

类内所有的方法里都能用

static 类型 变量名;

 public class Demo{
  static int age;//全局变量
 }

 

第一个java程序

创建源文件

 Demo1.java-----文件名
  public class Demo1{ ----类名
 
  }
  class Demo2{
 
  }
  class Demo3{
 
  }
 注:在源文件中,只有被public修饰的类必须与文件名相同;
  类名是不可重复的;

通过命令编译生成class文件

javac命令:编译生成字节码文件; javac Demo1.java-->执行-->生成 Demo1.class

执行class文件

java命令:执行字节码文件 java Demo1

数据类型(8种)

基本数据类型

整型

默认整型为int

  • byte 1个字节 范围:-128--127

  • short 2个字节

  • int 4个字节

  • long 8个字节

浮点型

默认浮点型为double,在float类型变量赋值时,常量后必须添加f和F

  • float 4个字节

  • double 8个字节

布尔类型

  • boolean 1个字节 真true/假false

字符型

  • char 2个字节 使用单引号定义 '',引号中只能写一个字符(数字、中文、英文、其它符号)

引用数据类型

字符串

数组

对象

类型转换

自动类型转换

目标类型 = 原类型

  • 小转大,整数转浮点数,字符转整数

     byte b=100;
  int c=b;  //类型兼容 byte short int long
  double f=c;//类型兼容 整型和浮点型
  c='a';//类型兼容 97

强制类型转换

目标类型 = (目标类型)原类型

  • 大转小,浮点转整数,整数转字符

     byte b=100;
  int c=b;  //类型兼容 byte short int long
  double f=c;//类型兼容 整型和浮点型
  c='a';//类型兼容 97
 
  b=(byte)c;//
  c=(int)f;
  char cc=(char)c;
 注:将源类型转为目标类型后,如果数值超出目标类型的范围,则会造成数据的不准确存放;

转义字符

在字符串中表达一些特殊符号时,使用转义字符

换行\n
制表符 \t
双引 \ "
单引 \ '
斜线 \ \
   

运算符

算数运算符

 + 加法/拼接(当+两侧任意一侧出现String字符串时为拼接)
 -
 *
 /
 %---求余数

比较运算符

 > 大于
 < 小于
 <= 小于或等于
 >= 大于或等于
 == 等于
 != 不等于
 注:比较结果一定是boolean类型  
     例:boolean flag=yushu==1;

赋值运算符

 = :将符号右边的值赋给左边的变量,例:int x=10; int y=x+100;

逻辑运算符

  • && 与 两个都真 ,条件为真

  • || 或 两个有一个为真,条件为真

  • !非 真变假,假变真

三元运算符

  • 表达式?结果1:结果2(一真二假)

条件判断语句

语法

if(表达式){
//执行语句1
}else{
//执行语句2
}
//表达式为真执行语句1 为假执行语句2


if(表达式1){
//执行语句1
}else if(表达式2){
//执行语句2
}else if(表达式3){
//执行语句3
}else{
//执行语句4
}
//表达式1为真执行语句1 为假判断表达式2 表达式2为真执行语句2 为假判断表达式3 表达式3为真执行语句3 为假执行语句4

循环语句

break; --终止当前循环;

while(条件){//变量:1 2 3 4 5 6 7 8 9 10
if(条件){//取值为5
break;
}
System.out.println(变量);//结果:1 2 3 4
}

countine; --结束本次循环;

while(条件){//变量:1 2 3 4 5 6 7 8 9 10
if(条件){//取值为5
continue;
}
System.out.println(变量);//结果:1 2 3 4 [5跳过本次循环]6 7 8 9 10
}

 

  • while循环

while(条件表达式){
//循环体
//迭代变量 i+=1
}
//条件表达式成立则一直执行循环体
  • for循坏

for(初始条件1;循环条件2;迭代变量4){
//循环体3
}
1 234 234 234....2不成立
  • 加强for循环

for增强循环:每循环一次,将数组中的元素依次赋值为变量;
for(数组类型 变量:数组名){
System.out.println(变量);
}
  • do{}while循环

先无条件执行,再进行条件判断

do{
//循环体
}while(条件表达式);

 

  • switch开关分支语句

    等值条件:变量与取值之间等于的关系;

    变量的类型:byte short int char String,枚举类型

switch(变量){
case 值1:
语句1;
break;
case 值2:
语句2;
break;
case 值3
...
break;
default: //默认以上皆不满足时,执行的语句部分;
....
break;
}
语法:当变量取值1时,执行语句1;如果变量取值2时,执行语句2;

方法

函数也叫方法;用于实现一个功能;

注:同一类内方法不能同名,除非重载

参数: 形参:定义方法时的形式参数,只有类型 实参:调用方法时的值,只有值 调用方法时,将实参的值依次赋给形参; 返回值: 将调用方法的结果通知调用者; 定义方法时,返回值类型与return后的值一致; 定义方法时,如果方法没有返回值,也可以在方法内使用空return 结束方法;

  • 主方法:main

public static void main(String[] args){
//语句
}
  • 方法的定义

public static void 方法名(){
//功能
}
注:
参数列表:类型、个数、顺序
返回值:return 值;return是方法的最后一句话;如果一个方法有多个出口,都必须有return语句;
  • 方法调用

  • 直接调用:
    方法名()
  • 方法类型

    • 有参数,有返回值;

    • 有参数,无返回值;

    • 无参,无返回值;

    • 无参,有返回值

  • 方法重载

    在同一类内,方法同名,参数列表不同;

    注:参数列表体现:参数个数、参数的顺序、参数的类型; 在类内出现相类似功能,但是参数不同,建议使用相同方法名定义;

  • 方法重写

 

子类重写父类的方法:

@Override用于检查重写的语法

方法名/参数列表(参数个数、顺序、类型都相同)/ 返回值类型形同;

访问修饰符大于等于父类方法;

抛出异常小于等于父类方法

  • 可变长参数

    可变长参数: 类型固定,但是个数不确定,个数表示0个或任意多个: 在参数列表中只能出现一个 必须出现在参数列表的最后 被当作数组使用;

    public static void test(int... x){ //x就是可变长参数
    //x当作数组使用
    for(int y:x){
    System.out.println(y);
    }
    }
    public static void test2(String... x){

    }
    //调用:
    test()
    test(10)
    test(20,30)
    ....任意个参数

构造方法(构造器)

特征:

每个类都有一个默认的无参构造器,用于创建对象;

方法必须与类名相同,

构造器没有返回值 没有void

作用:

为了创建对象

 

单元测试

在方法声明前:添加注解@Test

alt+enter:添加测试环境;add junit4 to classpath;

单独运行测试方法:有@Test注解的方法就可以以run as junit运行

注:测试类建议不要使用Test作类名;

数组

一维数组

存储多个相同的数据类型;有固定长度;

属性:length

  • 定义:数据类型[ ] 数组名 = new 数据类型[长度]

int[] arr = new int[n];
int[] arr = {1,2,3}
int[] arr = new int[]{1,2,3,4};
  • 访问 读/写

数组名[下标];
arr[n]
数组名.length //数组长度
  • 遍历:访问数组中所有元素

    • for

    • for each

  • 数组的排序

    • 冒泡排序

    方式:
    从第一位开始,相邻两位相比较,如果条件满足,执行两位置上的数相交换;依次,再将二三位的数相比较;
    每比较一次,在数组中最后位置处获得最值;

    int a[]
    int temp = 0;
    for(int j = a.length-1; j >=1;j++ ){
    for(int i = 0;i<j;i++){
    if(a[i]<a[i+1]){
    temp = a[i];
    a[i] = a[i+1];
    a[i+1] = temp;
    }
    }
    }

     

    • 选择排序

    方式:
    选择第一位与后续其它位相比较,如果条件满足,执行交换;依次再将第二位与其它位相比较,再将第三位与其它位相比较。。。。直到最后两个数比较完成

    代码:从大小到/数组 int[] a
    for(int i=0;i<a.length-1;i++){
    for(int j=i+1;j<a.length;j++){
    if(a[i]<a[j]){
    //两数交换
    }
    }
    }

     

  • 数组扩容

数组的定义要求固定长度和统一类型;

int[] arr=new int[10];---原数组
需求:向原数组增加一个新元素;
问题:覆盖原数组的内容/下标越界;
解决方式:扩容
扩容原理:
创建新数组;
将原数组的内容依次赋值给新数组;
再将新数组返回;return

二维数组

数组中的元素又是一维数组

  • 定义

int arr[][] = new int[行][列]
int arr[][] = {{0,0,0,},{0,0,0,},{0,0,0,}}
  • 访问:读/写

//赋值
数组名[行下标][列下标]=值;
//取值
数组名[行下标][列下标];
  • 遍历

数组名:brr
int[][] brr={
{1,2,3}, ---brr[0]
{4,5,6},
{7,8,9},
{10,11,12}
}
//for
for(int i = 0;i<arr.length;i++){
for(int j = 0;j<arr[i].length;j++){
System.out.print(a[i][j]);
}
System.out.println();
}
//加强for
for(int[] arr:brr){
for(int a:arr){
System.out.print(a);
}
System.out.println();
}

综合案列

登录;注册; 取款;存款;转账;修改密码;

[]数组; String[]user={"zhangsan"} String[]pass={"666"} String[]tel={"11111111"} int[]money={1000} 登录:用户名/密码 进行输入;比较;将输入的信息与存储的信息相比较 取款:输入取款金额;判断余额是否足够; 存款:放钞票;余额变化; 转账:另一个账户存在;余额判断;一方转出/另一方转入; 修改:输入原密码;验证正确;再次输入新密码,再次确认输入;密码保存;

字符串

  • 比较

用equals方法:

String str = "aaa"
String str1 = "bbb"
str.equals(str1)
  • int 与 String之间转换

字符串转int,只包含数字字符串"123456"

/字符串转换整型:
int num = Integer.Valueof("123456");//字符串"123456" 转为int类型的 123456
//整型转换字符串转换:
int num = 3;
String str = num+"";

面向对象

抽取公共部分的行为、特征定义为一个类.

class Car{
//全局变量:属性====特征
//颜色/品牌/排量


//方法:普通方法====行为
//行驶/倒车/撞车
}

属性(fileld,字段,全局变量,属性,实例成员属性)

特点:

定义在类内、方法外;

在类内处处可用

有默认值

重名:

局部变量可与属性重名,此时局部变量优先级高

 

public class 类名{
int age;//属性
public void fangFa(){

}
}

 

随机类(Random)

Scanner---import java.util.Scanner;导包

Random--import java.util.Random导包

注:使用本包以外的其它先引入环境/导包/直接使用; 导入一个包里的多个类时,可以使用 * 通配;

//创建对象
Random rd = new Random();
//产生一个随机数
rm.nextInt(范围) [0~范围)左闭右开
rm.nextInt(9) 产生0~9的随机整数
  • 随机字符串

String s =UUID.randomUUID().toString();

 

匿名内部类

相当于子类或实现类;多态使用场景;

	抽象类 引用变理=new 抽象类(){
//抽象类的子类
//必须重写抽象方法
};
普通类 引用变量=new 普通类(){
//普通类的子类
//选择性重写方法
};

 

对象

创建对象,也叫实例化对象;

创建对象四步:

1.堆内存开辟空间

2.初始化对象属性

3.实现构造器代码块内容

4.赋值给引用变量

Car car = new Car();//堆内存中开辟新空间,新空间地址存入到引用变量;
引用变量的类型与对象要兼容

This关键字

调用本类内容

  1. 调用属性和方法

this.属性名
this.方法名
  1. 调用本类其他构造方法

调用本类构造时,必须定义在构造方法中的第一句话

this调用构造方法的语句只能出现一次

this()---调用无参构造
this(参数列表)--调用有参构造,按参数的类型、个数、顺序匹配对应的有参构造;

super关键字

super代表父类

调用父类属性、方法(非私有的)

super.属性
super.方法
  • 调用父类的构造

super(参数):父类的构造
子类构造器中第一句默认super();
如果没有无参构造需要调用父类其他构造;
this()super()不能同时出现
super()的调用和super(参数)也不能同时出现;

 

封装

将复杂的实现过程封装在方法里,对外提供简单的调用

  • get/set

    • sexXXXX()通过方法传入数据(设置字段)

继承

父类:抽取子类共有的行为特征;

子类:可以调用父类的行为和特征,同时定义自己独有的行为和特征

//子类继承父类非私有成员
class 子类 extends 父类{

}

访问修饰符

private:仅限本类内访问

private 可以修改属性、方法、构造方法;

public:在任何地方都可以访问

public:可以修改类、方法、属性、构造方法

default:默认,当前类内、同一包

可以修饰类、属性、方法、构造方法

protected:当前类内、同一包、跨包后的子类中

用于修饰类、属性、方法、构造方法

多态

一种事务,多种不同形态:父类的引用指向子类的对象

 

子类和父类之间可以表现出多态;

任何一个子类都可以自动类型提升,提升为父类类型(宽泛的类型),可以将这个父类类型作为返回值/参数定义;达到统一编码,降低耦合度,减少冗余代码

场景一:将多态应用于返回值

class F3{}
class SF3 extends F3{}
class SF4 extends F3{}
class SF5 extends F3{}
class Factory{
public static 父类F3 getF3(int key){
//根据判断结果,返回不同的子类对象
if(key==1)
return new SF3();
else if(key==2)
.....
}
}

场景二:将多态应用于参数

class T{
public void test(){
Mster master=new Master();
Dog dog=new Dog();
master.feed(dog);
Cat cat=new Cat();
master.feed(cat);

master.feed(new Bird());
//以上参数中将子类对象自动向上类型提升,为父类Aniaml类型;
}
}

class Master{
/*public void feed(父类类型 参数){ //在方法调用时给参数传入具体的子类类型;
参数.eat();
}*/
public void feed(Animal obj){
//dog.eat();
obj.eat();
}
}
class Animal{
public void eat(){
System.out.println("eat....");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("dog eat....");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("cat eat....");
}
}
class Fish extends Animal{}
class Bird extends Animal{}

properties文件

在src下创建file-->后缀 properties的文件;

手动添加键值对:英文 键值=值

写程序:

//	创建对象:
Properties p=new Properties();
//加载文件:读文件的内容
p.load(当前类名.class.getClassLoader().getResourcesAsStream("properties文件名"));
// 根据键值获得值:
String 值=p.getProperty(键值)

向上转型(自动)

  • 父类类型 引用变量 = 子类对象

向下转型(强制)

子类类型 引用变量 = (子类类型)父类对象

  • instanceof 用于判断父类类型中的真实类型与目标类型是否一致,可以防止运行时异常---类型转换异常

    • 父类引用 instanceof 目标类型

Object obj=true;
if(obj instanceof String){//判断obj是否为String类型
String ss=(String)obj;
}

装箱

简单类型--》包装类;自动;

Integer num = 10;

拆箱

包装类--》简单类型;自动

Integer num = 10;
int a = num;

abstract关键字

抽象可以修饰类、方法

抽象类:被abstract修饰的类,不可被创建对象,类内可以包含抽象方法、普通方法

public abstract class 类名{
//属性、方法、构造方法(为子类而生)
//但是不能创建对象
//可能含有抽象方法
}
public class 子类 extends 抽象类{ //必须重写抽象父类的所有抽象方法

}

抽象方法:被abstract修饰的方法,没有方法体;只保留方法的声明,必须定义在抽象类内。

访问修饰符 abstract 返回类型 方法名(参数列表)异常 ;

static关键字(静态)

修饰属性、方法、代码块

  • 静态属性

属于类的属性,类的所有实例对象都共享一个属性,

可以使用类名直接访问,也支持对象访问

  • 静态方法

属于类;类的所有实例对象都共享一个方法;

可以使用类名直接访问,也支持对象访问

定义工具类里方法建议用static

静态方法里不能使用this和super,this和super代表对象,都需要先创建对象,而static与对象创建无关,有可能在对象创建之前就调用静态成员。

静态方法支持重载

静态方法可被继承

不支持重写和多态---多态情况下,不能访问子类独有的方法;

类加载

将类的信息读入到内存中保存

  1. 当前类创建对象

  2. 当前子类创建对象

  3. 调用当前类的静态属性、方法

  4. Class.forName("全类名")

静态代码块

执行:

在类被加载时,优先创建对象和动态代码块之前,执行一次。

静态代码块里只能使用静态代码块

类内可以定义多个静态代码块,定义序即执行序;

static{

}

 

动态代码块

执行:

每创建一次对象,就优先于构造器执行一次

类内可以定义多个动态代码块,定义序即执行序;

动态代码块内可以使用静态属性和非静态属性;

{

}

final关键字

  • final表示不可改变的。

  • final修饰属性时,这个属性称为常量;一般建议全大写字母表示,多个单词之间下划线连接,在定义时必须初始化

关键字

final---最终的,可修饰类、方法、属性,不可修改
static---静态的,可修饰方法、属性、代码块(类加载时自动优先执行),属性类的成员
类加载:创建对象/创建子类对象/访问类成员方法/访问类成员属性/Class.forName(全类名即包名+类名)--反射技术
abstract--抽象的,可修饰类、方法;
private--私有,可以修饰属性、方法、构造方法(不允许类外创建对象)
interface--定义接口的关键字(属性都是public static final;方法都是public abstract;)
class--定义类的关键字;
public--公共的,没有任何限制;
default--默认;switch中有一个默认条件;
instanceof--在向下强转前,判断引用类型是不是一个子类对象
protected--受保护的,跨包后的子类中可以被访问;
this--代表当前类及其所有子类的对象;
super--代表父类的对象;
extends---继承的关键字;表示当前类的直接父类,而且只能有一个直接父类;
class 类1 extends 类2---类的声明;
interface 接口1 extends 接口2,接口3,接口4....---接口之间是多继承
注:如果一个类1继承一个父类2,同时实现一个子接口1,此时类1可以重写父类2中的方法,并且必须重写接口1中所有抽象方法(包含接口2、接口3、接口4.。。。);
class 类1 extends 类2 implements 接口1{

}
implements--类实现接口的关键字;类与接口之间是多实现;接口与接口之间是多继承;
注:abstract与private、final、static能不能同时使用;

 

接口

特殊的抽象类,用interface修饰,没有构造器,不能创建对象,静态常量属性;

声明接口:

public interface 接口名{
//属性:公开静态常量属性,默认含有public final static
public static final int AGE=20;
String name="test";
//方法:公开抽象方法,默认含有public abstract
public abstract void login(String name);
}

实现类:接口与类之间的关系用implements表示;也叫多实现;

public class 实现类 implements 接口1,接口2,接口3{
//当前类必须实现(重写)接口中所有抽象方法
}

泛型

用来定义一个类型的代号,并不是真正的

public interface Compare<T>{  //其中T表示泛型代号,并不是有一个类叫“T"
T test();
}

分包使用

实体类:com.qf.pojo,主要用于封装数据

数据访问层: com.qf.dao---Data Access Object数据访问对象,定义接口 com.qf.dao.impl--dao的实现包,定义接口对应的实现 注:一个接口可以有多个实现类; 定义一个标准,由不同的需要确定不同的实现类;

测试类: 单元测试;junit

集合

Collection集合

用于储存对象

泛型:Collection<引用类型>,此时泛型不能为简单类型

  • 常用方法:

add(对象类型)

remove(对象):先查后删

查看所有:

  1. 迭代器遍历

	Iterator<泛型> it=集合.iterator();
while(it.haxNext()){ //判断是否有下一个元素
it.next(); //取出下一个元素
}
  1. for增强循环遍历

		for(泛型类型 变量:集合){
//变量---取出的一个元素
}
  • removeif(Predicate filter)

按条件执行删除时使用;
Predicate<泛型> filter=new Predicate(){
public boolean test(泛型 变量){
//添加条件,满足则返回true;否则返回false;
return true/false;
}
};

List集合

有序的、有下标、可重复

常用实现类:LinkedList、ArrayList、Vector、Stack

集合的底层实现是数组:查询效率高 ArrayList

集合的底层实现是链表:增删效率高 LinkedList

List子接口比父接口Collection定义了更多的方法,体现在下标的访问,get(index)根据下标获得元素

遍历集合

for(int i=0;i<list.size();i++){
list.get(i);//获得一个集合中的元素
}

set集合

无序的、不可重复、没有下标

全部继承Collection接口的方法无额外的方法

HasHSet:可以去除元素的重复录入;如果录入重复,集合拒绝录入

判重依据:hashcode()如果相同,则再根据equals()方法,如果返回true,则判为相同;
系统内置类:String/Integer/Date/Boolean....
自定义类:
重写hashCode():返回相同值;
重写equals():在hashcode值相同的情况下,再根据equals方法返回结果判断,true--重复;false--没重复;
注:在equals方法中一般是属性值之间的比较

TreeSet:可以按默认规则对元素实现排序;

排序依据:要求添加到集合中的元素要实现compareable接口
系统内置类:String/Integer/Date/Boolean....
自定义类:
实现Comparable接口,重写compareTo方法,在方法内定义排序规则E

Map集合

Map是容器,可用于存储键值对,键值唯一,值可以重复

  • 常用方法

新增:put(键值,值)  / putAll(Map map)
修改:replace(键值,值) / replace(键值,原值,新值) / 当键值重复时,新值也会覆盖原值;
删除:remove(键值) / remove(键值,值)
查看:
查所有键值:Set<键值的类型> set= keySet();
查所有值:Collection<值的类型> c=values();
获得键值对:Set<Entry类型> s=entrySet(); ---Entry表示一对键值对
getKey()键值/getVlues()值
根据键值查一个值:get(键值)---获得值

 

String常用类

  • indexOf(str[,local]):从左向右查询,查询子串首次出现的下标,如果查不到,则返回-1;local默认为0; 例:"abcdefghilmn".indexOf("a")---返回0 "abcdefghilmn".indexOf("a",5)---返回-1

  • lastIndexOf(str[,local]):从右向左查询,查询子串首次出现的下标,如果查不到,则返回-1;local默认为字符串的最大下标(length()-1);

  • length():字符串长度;

  • endsWith: 以某个子串结尾

  • startsWith: 以某个子串开始

  • split("str"):使用str字符将原字符串分割为一个字符串数组String[]

String 常量字符

String ss1="ABC";
String ss2="ABC";
//ss1==ss2;字符串地址相同
String ss3=new String("ABC");
String ss4=new String("ABC");
//ss3==ss4;地址不同
//以下比较结果都为true
ss1.equals(ss2)
ss3.equals(ss4)

StringBuffer 动态字符串,线程安全,效率低

StringBuffer a1=new StringBuffer();
a1.append("字");
a1.append("符");
a1.append("串");
//输出a1的内容:字符串

StringBuilder 动态字符串,线程不安全,效率高

StringBuilder a1=new StringBuilder();
a1.append("字");
a1.append("符");
a1.append("串");
//输出a1的内容:字符串

注:String不能修改原字符串内容,每次修改时会创建一个新字符串; StringBuilder/StringBuffer可直接修改原字符串内容

Date类

日期类:java.util.Date父类; java.sql.Date子类;

  • 创建时间

    1. new Date()----当前时间

    2. new Date(int年,int月,int日)----年月日

    3. new Date(int 年,int 月,int 日,int 时,int 分,int 秒)-----年月日时分秒

  • 格式转换

    SimpleDateFormate格式化日期
    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd")---字符串日期格式是yyyy-MM-dd
    sdf.format(Date日期对象)----将Date转为字符串输出
    sdf.parse(String)----将日期格式的字符串转为Date

    毫秒时间:从1970年1月1日 0时0分0秒开始计时;

异常

  1. Error 错误

  2. Exception 异常

Object Throwable Exception RuntimeException运行时异常:发生在程序运行过程中,可处理也可不处理; 编译异常:发生在文件编译时,必须处理,否则编译无法成功;

  • 异常处理方式:

1.try--catch:在程序中就地处理
try{
//可能出现异常的部分
//后续的代码可能无法执行
}catch(捕获的异常){
//出异常时执行的部分
}

2.throws:向上抛出异常,抛给调用者......JVM
//定义方法
public void test() throws 异常{

}
//调用方法
test()----try-catch/throws
例:
public class A{
public void testA() throws Exception{

}
}

public class B{
public void testB()throws Exception{
new A().testA();
}
}
public class C{
public void testC(){
try{
new A().testA();
}catch(Exception e){
e.printStackTrace();//打印异常轨迹
}
}
}

public class Test1{
public void test(){
new B().testB();//必须在此处理异常:throws/try-catch
new C().testC();//此时不需要处理异常;因为C内已将异常处理过;
}
}

properties.load()
  • 异常发生

手动抛出:throw new 异常名()
逻辑代码里出现
调用方法时,异常传递;
  • 自定义异常

定义:
class 异常子类 extends 异常父类{
public 异常子类(){
super();//默认无参构造
}
public 异常子类(String message){
super(message);//message传递的异常原因
}

}

 

线程

程序:静态的代码块

进程:运行的程序;在进程中至少包含一个线程

线程:包含在进程中的最小单位;抢占式执行;独立运行方法; 组成:cpu时间片、运行数据、逻辑代码;

创建线程1:

继承Thread类,创建线程类/重写run方法/创建线程对象/调用start()方法启动线程;

父类 Thread
new Thread(){
public void run(){
//线程任务
}
}.start();

class Thread1 extends Thread{
public void run(){
//线程执行的任务
}
}
测试:t1和t2之间是抢占式执行
Thread1 t1=new Thread1();
t1.start()

Thread1 t2=new Thread1();
t2.start()

创建线程2:

实现Runable接口/重写run方法/创建对象/创建Thread对象/借用thread对象调用start()方法启动线程;

class T3 implements Runable(){
public void run(){
//线程任务
}
}
测试:
T3 t=new T3();
Thread thread=new Thread(t);
thread.start();//启动线程

线程的生命周期:

  • 创建状态:新建一个线程类

  • 就绪状态:启动线程后,所有线程在处理就绪队列

  • 运行状态:获得CPU时间片,线程就将处理运行状态

  • 阻塞状态:运行中的线程,出现某个阻塞的原因,直到阻塞原因消失,线程又回到就绪状态;

  • 死亡状态:线程任务结束或被人为终止线程

同步安全:

多个线程在交替执行时可能因为争抢同一个临界而需要代码同步;

多个线程在交替执行是作为整体的部分不被打断;

实现线程安全:

synchronized关键字

使用同步锁:引用类型/类.class

synchronized(同步锁){
//同步代码块
}

Lock锁

和synchronized(锁对象)一样,具有互斥标识;
创建锁:Lock lock=new ReentrantLock();
创建一个监听线程的对象:Condition c=lock.newCondition();
定义同步代码块:具有原子性
lock.lock();
lock.unlock();
让出同步锁:c.await();
唤醒因await阻塞的线程:c.signal()/c.signalAll()

线程常用方法:

  • sleep(毫秒数)休眠时间

  • getName() 获得线程名字

线程的同步通信:

共享数据:临界资源

生产线程:向临界资源中存放数据

消费线程:从临界资源中取出数据

实现原理:通过同步锁的互斥标识控制生产线或消费线程

wait/notity

wait():让出同步互斥标识

notity():唤醒同一互斥标识的wait线程

  • 死锁

两个线程都持有对方所需要的锁,同时又等待对方的锁,

class Boy extends Thread{
public void run(){
synchronized(锁A){
。。。。代码
//sleep
synchronized(锁B){
。。。代码
}
}
}
}

class Girl extends Thread{
public void run(){
synchronized(锁B){
。。。。代码
//sleep
synchronized(锁A){
。。。代码
}
}
}
}
  • 线程池

减少线程的创建和关闭的耗时,创建线程池,调用线程池中的线程,用完后归还

创建线程池:
ExecutorService es=Executors.工厂类的方法
调用线程的任务:
es.submit(Runnable/Callable)
关闭线程池:
es.shutdown();

Callable接口

泛型接口,与Runnable相似;


new Callable<泛型>(){
public 泛型 call(){
//任务
return 返回值;
}
}

Future接口

实现类:FutureTask implements RunnableFuture{} //实现了Runnable和Future 接收Callable参数: FutureTask<泛型> task=new FutureTask(Callable类型参数); 接收任务返回值: task.get();

io流

流:数据传输的通道;

分类:

按方向:

输入流:从存储设备到程序

输出流:从程序到存储设备

按单位

字节流:一次读写操作一个字节,万能流

字符流:一次读写操作一个字符,限制读写文本,一个字符=两个字节,一个汉字是一个字符

按功能分:

节点流:具有起点和终点方向

过滤流(增强流):对节点流进行功能的增强

File类

表示物理路径下的文件或文件夹;

文件:有后缀、后缀就是文件类型

文件夹:又叫目录;

创建对象: File file = new File("文件地址")

file变量表示磁盘上的一个文件或文件夹

对文件执行io流操作;

对文件夹可以遍历;在文件夹里还可以创建文件/文件夹

常用方法:

file.isFile(); 表示是不是一个文件
createNewFile()创建一个新文件
mkdir()/mkdirs()创建一个新目录
delete()删除文件或空目录。
exists()判断File对象所对象所代表的对象是否存在。
getAbsolutePath()获取文件的绝对路径。
getName()取得名字。
getParent()获取文件/目录所在的目录。
isDirectory()是否是目录。
isFile()是否是文件。
length()获得文件的长度。
listFiles()列出目录中的所有内容。
文件夹
文件
renameTo()修改文件名为。
renameTo(File)
File f1=new FIle("d:/1.txt");
f1.renameTo(new File("d:/2.txt"));

io

  • 字节流:

字节输入输出节点流:字节输入输出节点流:InputStream/OutputStream
输入流 InputStream
输出流 OutputStream
文件字节输入输出节点流:FileInputStream/FileOutputStream
输入流 FileInputStream
输出流 FileOutputStream
读入方法:
从文件到程序,一次读一个字节:read();如果达到文件末,则返回-1;否则,返回ASCII值;一次读一个数组:read(byte[]b),返回实际读到的字节数;如果返回-1表示读到文件末尾;
写出方法:
从程序到文件,一次写出一个字节:write();
关闭流:
close();


缓冲输入/输出字节过滤流:增加了缓冲区,提高了IO执行效率;
BufferedInputStream/BufferedOutputStream
注:没有增加其他的方法,只多了缓冲区;
在程序和文件之间增区的用于保存数据的区域;
如果是输出流,程序向文件中写出的内容,因为保存在缓冲区,需要及时清空缓冲区;
清空缓冲区的方式:
缓冲区满自动清空,缓冲区默认大小8192字节(8k);1k=1024b
关闭流时,调用close方法;
强制清空,调用fiush方法;


对象输入/输出字节过滤流:增加了缓冲区,还可以对八种基本类型及字符串、对象进行读写操作;
先写出操作:ObjectOutputStream
Write基本类型();
writeUTF(字符串);
writeObject(Object)
在读入操作:ObjectInputStream
read基本类型();
readUTF();返回String
readObject();返回Object
注:对对象写出,叫序列化;
从文件中读一个对象,叫反序列化;
对读写操作的对象要求实现序列化接口Serializable,不需要重写方法,只是作为序列化和反序列化版本比较的标识(比的是serialUID)


打印输出流:
PrintStream(OutputStream/File/String)

字符流

抽象父类:Reader/Writer		
读:
read()
read(char[])
写:
write(int)
write(String)
write(char[])
字符输入/输出节点流:
FileReader/FileWrite

字符输入/输出缓冲流:
BufferedReader/BufferedWrite
提供了缓冲区,提高IO读写效率;
特别:一次读一行;read()/readLine()无东西返回null

打印字符输出过滤流:
PrintWrite(Write/File/String/OutPutStream)
Print/Println向外写出一行

转换流

标准输入流:
System.in;InPuttream类型
表示从键盘录入
标准输出流
System.out,OutPutStream类型
从控制台输出

网络编程

IP:网络中的每台设备的唯一一个点分十进制表示的地址

端口号:设备中的一个端口,表示一个程序,例:mysql--3306;oracle-1521;

Socket:也叫套接字,是网络的一个通信节点;

基于TCP协议的编程,基于套接字的编程方式:

第一步:双方(客户端与服务器)建立连接:
服务器:Sever
建立服务器:SeverSocket ss = new SeverSocket(端口号);
等待客户端连接:Socket socket = ss.accept();
开始通信:基于字节节点流
客户端:Client1
连接服务器:Socket socket = new Socket(服务器ip,端口号);
开始通信:基于字节节点流
客户端:Client
客户端:Client
...
第二步:双方通信,基于字节节点流InputStream/OutputStream
socket.getInputStream();
socket.getOputStream();

群聊:
建立正常通信
持续的收发消息
在客户端与服务器端添加while(true)实现双方通信
多客户端连接
在服务端接收、发消息单独定义为一个线程;
在客户端连接到服务器后,accept方法后,将所有的通信节点Socket收集起来(收集到List中);
启动每个线程;
实现群聊
在客户端收消息时定义在线程类中;
只要客户端与服务器端之间建立连接,在new Socket之后启动客户端收消息的线程;
在服务端发送消息时,需要将上一步收集到的所有Socket遍历并给每个客户端发送消息;
处理退出(线下)问题
客户端程序下线,输入“bye”,并且将当前客户的收消息线程结束掉,调用stop方法;
服务器端程序处理下线客户端,将该客户端从list集合中移除;

基于UDP协议的编程:无连接的传输层通信协议

发送方:--客户端
DatagramSocket socket = new DatagramSocket()
socket.send(数据包)
接收方:--服务器
DatagramSocket socket = newDatagramSocket(端口)
socket.receive(数据包)----阻塞式接收原理
拆包:获得发送方的相关信息
数据:getData()
内容长度:getLength()
主机:getAddress()
端口号:getPort()
数据包:
当作为空包:DatagramPacket packet = new DatagramPacket(byte[],int);
接收到数据的包并重组新包:
DatagramPacket packet = newDatapragramPacket(byte[],int,InetAddress,int端口);

反射技术

类对象:Class类型封装类(任意类)的成员信息,包括:属性、方法、构造。。。。

注:任何类的对象都是Class 每个类只有一个类对象

获得类对象

  1. 实例.getClass()

  2. 类.class

  3. Class.forName("全类名");//全类名:包名+类名

获得方法:

Method m = 类对象.getMethod("方法名",Class...方法中参数的类对象);
获得所有方法:
Method[] m1 = 类对象.getDeclaredMethods();
获得一个方法:
Method m2 = 类对象.geetDeclaredMethod("方法名",Class...参数列表类对象)

反射创建实例:

Object obj=类对象.newInstance();

调用方法

m.invoke(obj,方法中的实参)

构造器

获得构造:
获得所有构造:
Constructor[] c = 类对象.getDeclaredConstructors()
获得某个构造:
Constructor c = 类对象.getDeclaredConstructor(参数的对象)
调用构造:
c.newInstance(实参的值)

获得属性

获得一个属性
getDeclaredField(属性名)
获得所有属性:
getDeclaredFields();

常用方法

含义方法名返回类型
获得修饰符 getModifiers() int
获得方法名 getName() String
获得返回类型 getReturnType() Class
获得参数列表 getParameterTypes() Class[]
获得异常 getExceptionTypes() Class[]
获得所有构造器 getDeclaredConstructors() Constructor[]
获得一个构造 getDeclaredConstructor(Class...param) Constructor
调用构造器 newInstance(Object...参数值) Object
获得所有方法 getDeclaredMethods() Method[]
获得一个方法 getDeclaredMethod(方法名,Class...参数的类对象) Method
调用方法 invoke(实例,Object...实参的值) Object
获得所有属性 getDeclaredFields() Field[]
获得一个属性 getDeclaredField Field

自定义注解

元注解:注解中的注解

@Target表示注解的使用位置:可在类(TYPE)、方法(METHOD)、属性(FIELD)、构造等

@Retention注解生效的时间

class:注解记录在class文件中,运行java程序时,jvm不会保留,此为默认值

runtime:注解记录在class文件中,运行java程序时,jvm会保留,程序可以通过反射获取该注解

source:编译是直接对齐这种策略的注释

@Target(ElementType.METHOD,ElementType.TYPE,ElementType.FIELD)
@Retention(RetenttionPolicy.RUNTIME)
public @interface Mapping{
String url(); //没有默认值,必须在使用时添加值
int age=20;//默认20
}

使用:

@Mapping(url = "/user")
public 类名{
@Mapping(url = "/selectAll")
public void select(){
sout("查看所有方法")
}
@Mapping(url = "/deletetAll")
public void delete(){
sout("删除所有的方法")
}

}

测试

模拟前端:在浏览器中输入一个字符地址: user/selectAll
在后端测试:
获得一个类对象:
Class c=UserController.class;
获得类的注解内容:
Mapping m=(Mapping)c.getDeclaredAnnotation(Mapping.class);
String u1=m.url;
遍历出这个类对象中所有方法,判断每个方法中是否含有注解Mapping,以及区分注解中url的值是不是与前端的请求地址一致,如果一致,则调用该方法;
Method[] method=c.getDeclaredMethods();
for(Method m:method){
Annotation an=m.getDeclaredAnnoatation(Mapping.class);
if(an!=null){
Mapping mapping=(Mapping)an;
String u2=mapping.url;
//将前端输入的地址与当前行到的(u1+u2)相比较,比较一致时调用当前的 m;
//m.invoke();
}
}

三次握手、四次挥手

  • 三次握手: 第一次:客户端向服务端发起连接 第二次:服务端接收请求并进行确认 第三次:客户端对服务端的响应进行确认

  • 四次挥手: 第一次:客户端发起挥手请求 第二次:服务器端接收挥手请求 第三次:服务器发起关闭连接 第四次:客户端进入关闭连接的状态

  • 通信:基于字节节点流 socket通信节点 socket.getInputStream socket.getOutputStream

 

UDP编程:无连接,相对通信效率高

数据报的一种通信方式:数据的携带使用的是DatagramPacket DatagarmSocket创建连接 send(packet) receive(packet) 拆包:在DatagramPacket中调用getData()获得数据相关信息,将字节数组转为字符串

网络编程实现上传 客户端: 1.读客户端本地的文件;InputStream is=new FileInputStream(本地文件) 2.将文件发到服务器端;OutputStream os=socket.getOutputStream(); 6.接收服务端发回的处理结果;InputStream is2=socket.getInputStream(); 服务器端: 3.从客户端读文件;InputStream is=socket.getInputStream(); 4.将文件保存到服务端;OutputStream os=new FileOutputStream(本地文件); 5.将上传的结果发回到客户端; OutputStream os2=socket.getOutputStream();

网络编程实现下载 客户端: 1.连接服务器; 4.从服务器读文件:InputStream is=socket.getInputStream(); 5.保存到本地:OutputStream os=new FileOutputStream(本地文件); 服务器端: 2.从本地读文件:InputStream is=new FileInputStream(本地文件) 3.向客户端发送文件;OutputStream os=socket.getOutputStream();

网络编程实现登录 客户端: 1.发送昵称和密码: OutputStream os=socket.getOutputStream(); 4.接收服务器端发的信息:InputStream is=socket.getInputStream(); 服务器端: 1.接收客户端的信息:InputStream is=socket.getInputStream(); 2.读本地的文件内容:InputStream is2=new FileInputStream() 3.将本地文件内容与接收到的信息相比较,并将比较结果发回到客户端:OutputStream os=socket.getOutputStream() 网络编程实现注册 客户端: 1.发送昵称和密码: OutputStream os=socket.getOutputStream(); 4.接收服务器端发的信息:InputStream is=socket.getInputStream(); 服务器端: 1.接收客户端的信息:InputStream is=socket.getInputStream(); 2.向本地的文件中写内容:OutputStream os=new FileOutputStream(); 3.将注册结果发回到客户端:OutputStream os=socket.getOutputStream()

枚举

固定实例,是一个终止类,内部属性值是静态常量;声明用enum关键字;同时可以出现抽象abstract方法;

枚举类的定义

enum 类名{
实例1,实例2,实例3//必须定义在第一行
}

有构造的枚举

enum 类名{
实例1(实参),实例2(实参),实例2(实参);//必须定义在第一行

类名(性参数){

}
}
调用枚举的实例、方法时,枚举的所有实例均提前创建完毕

抽象枚举类:含有抽象方法的枚举类

enum 类名{

//abstract void test();

实例1(){
//重写部分
},

实例2(){}.....//抽象枚举类的实例就是它的普通子类;此时必须重写抽象方法

}
自定义了抽象方法的枚举类会自动提升为抽象枚举类;

设计模式

一套解决特定问题的方式;长哟领的设计模式有23种;

  • 工厂设计模式:用于动态创建对象

class 类名{
public static 接口/父类 方法名(参数){
//根据参数判断
return 实现类对象/子类对象;
}


}
  • 模板设计模式:抽象类/抽象方法/普通方法;把变化的代码定义在抽象方法里由子类重写;普通方法实现对抽象方法的调用;

abstract class 类Template{
abstract void test1();
abstract void test2();

public void normal(){
//固定代码
test1();
//固定代码
test2();
//固定代码
}
}
子类 extends Template{
//重写test1
//重写test2
}
子类2 extends Template{
//重写test1
//重写test2
}
测试:Template t1=new 子类();
Template t2=new 子类2();
t1.normal();
t2.normal();
  • 单例模式:只允许创建一个该类的对象。

私有构造器:在类外不允许被访问private

公有静态获得对象的方法:

私有静态属性:保证对象必须是唯一的

//懒汉式
class SingleTon1 {
//私有构造
private SingleTon1() {

}
private static SingleTon1 s;//私有静态---只属性类
//公有静态获得对象
public static SingleTon1 getInstance() {
if (s == null) {
s = new SingleTon1();
}
return s;
}
}




//饿汉式
class SingleTon2 {
//私有构造
private SingleTon2() {

}
private static SingleTon1 s= new SingleTon1();//私有静态---只属性类
//公有静态获得对象
public static SingleTon1 getInstance() {
return s;
}
}

JDK8特性

Lambda表达式:对匿名内部类格式的简化

lambda

语法:
(参数)->{//方法体}

函数式接口:接口中的方法只能定义一个抽象方法;
void test();---无参无返回值的方法;----
接口类型 变量 =()->{ sout("无参无返回值的方法")};
void test2(int x,int y);---有参无返回值的方法---
接口类型 变量 = (m,n)->{sout(m+n)}
int test3();---无参有返回值--------
接口类型 变量 = ()->值;
int test4(int x, int y)---有参有返回值----
接口类型 变量 = ()->x+y;
接口类型 变量 = ()->{return x+y;};

Straeam流

Stream中保存对集合或数组的操作

使用步骤:
创建流:
-通过Collention对象的stream()或parallelStream()方法
-通过Arrays类的stream()方法。
-通过Stream接口的of()、itearte()、generate()方法。
-通过InStream、longStream、DoubleStream接口中的of、range、rangeClosed方法。
中间操作:
-filter、limit、skip、distinct、sorted
-map
-parallel
终止操作:
-forEach、min、max、count
-reduce、collect

案例:

创建流:
Stream<Integer> stream = Stream.of(10,20,33,55,100)
//中间操作:filter
//终止操作:forEach
stream.filter(x->x%2==0).forEach(System.out::println);

日期类型

  • java.util.Date

常用于声明属性:
private Date birth;
  • java.sql.Date

在jdbc中支持的数据类型:
java.util.Date与java.sql.Date之间的转换;
new java.sql.Date(new java.util.Date().getTime());
  • java.tetx.SimpleDateFormat(格式化日期)

将java.util.Date的日期与字符串之间的转换:
parse
format
  • java.util.Calender日历类

实例化:Calendar c = Calendar.getInstance();
调用实例方法:
c.set(int year,int month,int date);
c.get(字段名);---c.get(Calendar.YEAR)获得某个字段的值
调用字段:
Calender.YEAR
Calendar.Day_OF_MONTH
  • LocalDateTime jdk8的日期类

创建时间:
LocalDateTime localDateTime = LocalDateTime.now()
LocalDateTime localDateTime2 = LocalDateTime.of(year,month,dayOfMonth,hour,minute)
  • DateTimeFormatter jdk8格式化日期类

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
format:通过这个方法转为字符串表示;

LocalDateTime.parse("2020-02-10 10:20:35",dtf);通过这个方法将字符串转换为LocalDateTime

 

posted @ 2022-01-04 10:45  永远的幼稚  阅读(131)  评论(0)    收藏  举报