java学习文档

一JavaSE学习:

一.Java基础

1.Java的发展

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

Java具有简单性、面向对象、分布式健壮性安全性、平台独立与可移植性、多线程、动态性等特点 [2] 。Java可以编写桌面应用程序、Web应用程序、分布式系统嵌入式系统应用程序等。

Java的三个版本:

(1)Java SE(基础)

(2)Java ME(Android)

()2)Java EE

2.安装JDK

JDK(Java Development Kit)称为Java开发包或Java开发工具,是一个编写Java的Applet小程序和应用程序的程序开发环境。JDK是整个Java的核心,包括了Java运行环境(Java Runtime Environment),一些Java工具和Java的核心类库*(Java API)*。

另外,可以把[Java API](https://baike.baidu.com/item/Java API)类库中的Java SE API子集和Java虚拟机这两部分统称为JRE(JAVA Runtime Environment)JRE是支持Java程序运行的标准环境 。

JRE是个运行环境,JDK是个开发环境。因此写Java程序的时候需要JDK,而运行Java程序的时候就需要JRE。

配置环境变量:

计算机右键——属性——高级系统设置——高级——环境变量——系统变量
path 编辑 变量值 :%JAVA_HOME%\bin;
JAVA_HOME 新建 变量名JAVA_HOME 变量值 JDK安装路径
classpath 新建 变量名classpath 变量值
.;%JAVA_HOME%\jre\lib\rt.jar;
%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;

win+r cmd , java -version

Java程序执行原理:
Java高级语言.java
编译 字节码文件.class
JVM 解释 得到程序执行结果

写Java程序 保存文件类型选择所有文件,
文件名跟public修饰的class名称一致

找到文件存放目录,按住shift右键,打开命令行窗口
编译javac 类名.java,产生字节码文件.class

执行java 类名

3.学会使用java开发工具

Idea的激活:

1关闭IDEA,进入到IntelliJ IDEA的安装目录,找到bin目录进入,将JetbrainsCrack-2.6.10-release-enc.jar文件复制到bin目录下,
例如:D:\Software\JetBrains\IntelliJ_IDEA\bin\。
2将idea.exe.vmoptions 和 idea64.exe.vmoptions 用记事本打开,分别在两个文件的末尾加上下面一行:
-javaagent:D:\Software\JetBrains\IntelliJ_IDEA\bin\JetbrainsCrack-2.6.10-release-enc.jar
3接着双击 idea64.exe,在 active code栏随便输入任意字母,点击ok即可。打开软件后点Help-About看到License可以用到2099年。

二.java基础语法

1.注释与标识符

(1)行内注释 //

(2)多行注释 /**/

(3)文档注释/** */ (javadoc生成帮助文档)

(4)关键字

2.数据类型及运算符

基本数据类型:

整形:

byte short int long 进制转换
8位 16位 32位 64位

浮点数:

float double BigDecimal(金融)
32位 64位

字符:

char (Ascil,utf-8,Unicode,转义字符)
16位

boolean 值true、false
引用数据类型:
String、new(数组、类、接口)

类型转换:

1.自动类型转换 低转高

2.强制类型转换 高转低 (低)高

栈内存:存放基本数据类型、引用
堆内存:存放引用数据类型的对象
String name = “张三”;

变量命名规则:

字母A-Za-z、数字0-9、下划线_、美元符$
1.见名知意,2.驼峰命名3.类,首字母大写,驼峰命名
不能以数字开头 name1
不能使用关键字 int

作用域:

1.类变量(static)

2.实例变量

3.局部变量(方法内部的)

常量命名:

大写+下划线

final int WEEK_DAYS = 7;

运算符:

算数运算符:+ - * / % ++ –

赋值运算符 =

关系运算符 > < >= <= == != instanceof

逻辑运算符 && || !

位运算符 & | ^ ~ >> << >>>

条件运算符 ? :

扩展运算符 += -= *= /=

== 双等号左右两边是数值类型,比较左右两边数字是否相等
== 双等号左右两边是对象类型,比较两个对象是否相等,即比较地址是否相等.
比较两个字符串对象的值相等不相等,equals()方法

3.包机制

1.域名倒写;2.防止命名冲突;3.package;4.import导入

4.JavaDoc

1.JDK帮助文档

2.javadoc:

@author

@Version

@Since

@param

@return

@throws

5.流程控制

1.顺序结构

程序默认的结构,自上而下的执行

2.选择结构

(1)if单选择结构

(2)if-else双选择结构

(3)if-else,if-else多选择结构

(4)if-else if-else嵌套选择结构

if语句的一般形式如下:

if(表达式)语句1

[else语句2]

if语句中的“表达式”可以是关系表达式、逻辑表达式,甚至是数值表达式。其中最直观、最容易理解的是关系表达式。所谓关系表达式就是两个数值进行比较的式子。

int i = 1
if(i>3{
     i--;
}else{
    i++;
}
   
3.Switch开关

该语句也是多分支选择语句,到底执行哪一块,取决于开关设置,也就是表达式的值与常量表达式相匹配的那一路,它不同if…else 语句,它的所有分支都是并列的,程序执行时,由第一分支开始查找,如果相匹配,执行其后的块,接着执行第2分支,第3分支……的块,直到遇到break语句;如果不匹配,查找下一个分支是否匹配。这个语句在应用时要特别注意开关条件的合理设置以及break语句的合理应用。

int i=1;
switch(i){
    case 1:
        i++;
        break;
    case 2:
        i--;
        break;
    default:
        i=10;
        break;
}

break与continue及return

break:跳出循环结构,执行循环后面语句

continue:跳出当前循环,进行下一次循环

return:返回一个值,结束方法的运行

4.循环结构

在java语言中,有三种类型的循环语句:for语句、while语句和do While语句。分别介绍如下:

1.for循环:当型循环语句,它很好地体现了正确表达循环结构应注意的三个问题:

⑴控制变量的初始化。

⑵循环的条件。

⑶循环控制变量的更新。

(4)表达式;

int sum = 0;
forint i=1; i<20; i++{
    sum = sum+i;
}

(5)增强for循环

forint a : int[] sum){
    System.out.println(a)
}

2.while结构循环为当型循环(when type loop),一般用于不知道循环次数的情况。维持循环的是一个条件表达式,条件成立执行循环体,条件不成立退出循环。

  • while语句格式为:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RXRontHX-1663330627375)(https://bkimg.cdn.bcebos.com/pic/9825bc315c6034a812ecc274ca1349540923763c?x-bce-process=image/resize,m_lfit,w_440,limit_1/format,f_auto)]

►while(条件表达式)

► 循环体

►每次执行循环体前都要对条件表达式进行判断。

这里的表达式是循环能否继续下去的条件,而语句是循环体。只要表达式为真,则执行循环体内语句。否则终止循环,执行循环体外语句。

3.do while

►do…while语句结构为直到型循环(until type loop),也用于不知道循环次数的情况。do…while和while的区别在于do…while结构是执行完一遍循环体再判断条件。

  • do while语句格式为:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7prrQgfh-1663330627376)(https://bkimg.cdn.bcebos.com/pic/b8389b504fc2d562b3e3aa18e61190ef77c66c5f?x-bce-process=image/resize,m_lfit,w_440,limit_1/format,f_auto)]

►do

► 循环体

►while(条件表达式);

►每执行完一次循环体,do…while结构都要判断一下条件表达式。

程序进入do while循环后,先执行循环体内语句,然后判断表达式的真假,若为真则进行

下一次循环,否则为假则终止循环。该循环语句的特点是,表达式为假时也执行一次循环体内语句。

总的说来,for和while循环是在顶上测试循环终止条件,而do while循环是在之后,在底部进行测试所以循环体至少要执行一次。

三.数组

1.基本数组及定义

数组(Array)是有序的元素序列。 若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式。 这些有序排列的同类数据元素的集合称为数组。

数组是用于储存多个相同类型数据的集合。

定义:

(1)new int[5]

(2){1,2,3,4,5}


import java.util.Arrays;
//作业:将一堆无序的字符进行排序后,顺序和逆序输出。
public class Homework7 {
    public static void main(String[] args) {
        char nums[] = {'a','c','u','b','e','p','f','z'};
        Arrays.sort(nums);  //顺序排序
        System.out.println("循环顺序输出");
        for (int i=0;i<nums.length;i++){
            System.out.print(nums[i]+"\t");
        }
        System.out.println();
        System.out.println("逆序排序并输出");
        for (int i=nums.length-1;i>=0;i--){      //逆序排序
            System.out.print(nums[i]+"\t");     //进行输出
        }
    }
}

2.多维数组

二维数组以上的数组

int arr[][] = new arr[2][4];

Arrays工具类

排序算法:1.冒泡排序2.选择排序3.插入排序4.快速排序5.归并排序6.希尔排序7.堆排序8基数排序

四.面向对象

1.类的组成

类由修饰词+返回值类型+类名+类体组成。

 public static void Student{
   String name;      //类体
    int age;
public say(String s){
    System.out.println("说了一句话");
}
}

2.方法的构造

java 里面的方法类似于C语言里面的函数,由修饰词+返回值+方法名(有参/无参){方法体}组成。

public say(String s){
    System.out.println("说了一句话");
}

1.方法返回值类型void,则方法体可以不写return关键字
方法返回值类型:(String ,int等),则必须写return关键字

2.返回值类型:方法体执行完成以后得到的值
方法参数:方法执行的时候已知条件

3.成员变量:类的变量,作用域是整个类中都可以使用,成员变量JVM给初始值
局部变量:方法的变量,作用域是当前方法体内部,局部变量JVM不给初始值

4.方法定义的时候,参数——形式参数——声明
方法调用的时候,参数——实际参数——实际的值

5.Java程序的包package相当于磁盘里的文件夹

6.方法调用:

(1)类名.方法

(2)对象.方法

7.方法重载:名字相同,参数列表不同

8.命令行传参: 给main方法传递参数

9.可变长参数: … 必须放在最后一个参数

10.递归:自己调用自己,给自己一个出口

3.什么是面向对象

1.面向对象编程(Object-Oriented Programming,OOP).

2.面向对象编程的本质就是:以类的方式组织代码,以对象的方式组织(封装)数据。

3.对象,是具体的事物。类,是抽象的,是对对象的抽象。

4.从代码运行角度看,先有类后有对象,类是对象的模板。

5.构造方法 构造的重载:

(1)默认无参构造

(2)如果手动定义了有参构造就必须要手动再加一个无参构造

(3)单例模式,需要构造器私有

6.new对象 栈存放引用,堆存放具体的对象

4.面向对象的分析方法

1.找到类

2.找到属性

3.找到方法

五.对象的三大特性:

1.封装

通常来说,就是数据的隐藏;指禁止直接访问一个对象中数据的实际表示,而通过操作接口来访问。也就是***属性私有,通过get/set***来得到被private定义的属性或者方法。

实现封装步骤:
第一步:把类的共有属性改成私有属性,即用private修饰属性
第二步:提供公有的方法对属性访问(对属性赋值,对属性取值)
第三步:在赋值方法中,用控制语句实现不合理赋值

2.继承

1.继承的定义

1.继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖,组合,聚合等。

2.继承关系的两个类,一个为***子类(派生类)***,一个为父类(基类)。子类继承父类,使用关键字extends来表示。

3.子类和父类之间,从意义上讲应该具有**“is a”**的关系。

继承关系:不能继承的情况如下
父类的private修饰的成员变量和成员方法,则子类不能继承
子类和父类不在同一个包package,父类的默认访问修饰符修饰的成员变量和成员方法,则子类不能继承
父类构造方法,子类不能继承

2.继承的表示
public class Student extends Person{
super();  //引用父类的构造方法。
}
3.方法的重写

1.重写的是方法,与属性无关。

2.子类和父类中具有同样的方法,子类重写方法后,调用引用了父类的方法后将会引用子类的方法。

3.继承关系前提下才讨论重写:
方法名相同
参数列表相同
返回值类型相同或是子类方法的返回值类型子类
方法访问权限不能比父类严格

3.多态

1.多态的定义

1.即同一方法可以根据发送对象的不同而采用多种不同的行为方式。

2.一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多。

3.多态存在的条件:

(1)有继承关系

(2)子类重写父类方法

(3)父类引用指向子类对象

4.注意。多态是方法的多态,属性没有多态性。

  1. instancesof(类型转换) 引用类型,判断一个对象是什么类型。
Student Student = new Student();
System.out.println(Student instanceof student);  //true
System.out.println(Student instanceof person);  //true
System.out.println(Student instanceof object);  //true
System.out.println(Student instanceof String);  //报错
//student 和 String 无关

4.扩展

1.static 类

静态,可以修饰变量与方法,成为类变量和类方法。它与类一同加载,在类里面。

静态代码
static关键字修饰
修饰成员变量,例如:static final String NAME = “张三”;
修饰成员方法,static在返回值类型的前面,也就是访问修饰符的后面
例如:public static void main()
通过类名访问成员变量和成员方法
修饰代码块
静态代码块在构造方法之前执行
静态成员变量和成员方法,第一种,通过类名访问;第二种,对象名
非静态成员变量和成员方法,首先初始化对象,然后通过对象名访问

public Test{
static int age;   //静态变量
static void print(){    //静态的方法。
}
    public static void main(String arg[]){
        Test.age;   //类变量可以直接用类名调用。
        prinf();   //类方法可以直接在类中调用。
    }
}

2.final 类

定义:修饰为常量,不能够被子类继承。

(1)abstract 抽象类:(类的一种)类:单继承(接口可以多继承)

(2)abstract类,不能被new出来,只能靠子类去实现它:约束!

(3)抽象类中可以写普通方法。

(4)抽象方法必须在抽象类中。

public abstract class Action{
    //抽象类,起约束,子类来实现
    //abstract,抽象方法,只有方法名字,没有方法的实现。
public abstract void dosomething();//没有花括号
}

(5)new一个类,也就是给类实例化,new得到的属性方法为实例方法,与类方法不同。

Student student = new Student();  //实例化
Student.name;   //实例属性
student.age;
student.say();  //实例方法
3.访问修饰符的表

private——在类内部可以
default——默认访问修饰符——在同一个包可以
protected——同一个包,子类可以
public——任意可以

4.抽象:

父类被重写的方法的方法体代码
抽象方法abstract修饰——没有方法体{}
方法是抽象方法则必须写在抽象类中

5.内部类

1.局部内部类

2.静态内部类

3.匿名内部类(重点)

六.接口

1.接口的定义

(1)接口都需要有实现类

(2)接口可以扩展程序功能

(3)接口可以继承一个接口

(4)接口表现为一种约定(标准)(规范)

(5)接口的方法只是定义具备某种能力(抽象方法)

public interface UserService{
    //接口中的所有定义其实都是抽象的 public abstract
    void add(String name);
    void delete(String name);
    void update(String name);
    void query(String name);
}
public interface TimeService{
    void timer();
}
/*
抽象类:extends
类 可以实现接口Implements 接口
实现了接口的类,就需要重写接口中的方法
多继承~利用接口实现多继承。
*/
public class UserServiceImpl implements UserServiceTimeService{
    public void add(String name){
    }
     public void delete(String name){
    }
 	 public void update(String name){
    }
	 public void queryd(String name){
    }
     public void timer(){
         
     }
    }
}

2.接口的作用:

(1)约束

(2)定义一些方法,让不同的人实现

(3)public abstract //定义抽象的方法

(4)public static final //定义静态的常量使用

(5)接口不能被实例化~接口中没有构造方法

(6)implements可以实现多个接口

(7)只有一个方法的接口叫做函数式接口,可以使用lambda表达式简化

3.总结:抽象类和接口:

相同:

都表示抽象概念,接口的抽象概念,能力,约定

都不能被实例化,不能用new初始化一个抽象类或者接口

抽象类中可以出现抽象方法,接口中都是抽象方法

不同:

抽象类中可以有抽象方法,也可以有一般方法(成员方法)

接口中只能出现抽象方法

抽象类一般作为父类,可以被子类继承,复用

接口,通过实现类可以扩展程序功能

一个类只能继承一个父亲,但可以实现多个接口

七.异常

Throwable:

(1)Exception

运行时异常:

1/0,ClassNotFound,NullPoint,UnKownType,下标越界…

检查型异常

(2)ErrorAWT错误

JVM错误

StackOverFlow,OutOfMemory

1.异常的定义

java用throw关键字抛出一个Exception子类的实例表示异常发生

2.抛出异常

用throw new +异常 / throws +异常名


    public void setAge(int age) throws Exception {  //声明异常
        if (age >= 1 && age <= 100) {
            this.age = age;
        }else {
            throw new Exception("年龄错误,年龄介于1到100之间"); // 抛出异常
        }
    }

3.捕获异常

try {
            student.setAge(input.nextInt());  //可能含有的异常

        } catch (Exception e) {  // 捕捉异常
            e.printStackTrace();  // 打印输出异常
        }finally{
            System.out.println("当前年龄为:" + student.getAge());
        }

异常处理五个关键字:

try

catch(先小后大)

finally

throw(手动抛出异常)

throws(方法抛出异常)

4.自定义异常

public class +异常名+ extends +Exception


public class AccountException extends Exception{    //定义一个异常
    String message;
    public AccountException(String message) {   // 异常构造方法
      this.message = message;
    }

    @Override
    public String getMessage() {   // 打印异常信息
        return message;
    }
}

八.常用类

1.Object类

hashcode()

toString()

clone()

getClass()

notify()

wait()

equals()

2.String 类

不可变性 final 操作量较少

3.StringBuffer类

可变长 append()多线程数据量较大 效率低,安全

StringBuild

可变长,单线程数据量较大 效率高,不安全

4.Date与Calendar类

Date

SimpleDateFormat yyyy-MM-dd HH:mm:ss

Calendar(建议使用)

5.Math类

常见的数学运算

6.Random类

生成随机数 UUID

7.File类

创建文件,查看文件,修改文件,删除文件

8.包装类

自动装箱和拆箱

九.集合框架

定义:

Java中的集合类:是一种工具类,就像是容器,存储任意数量的具有共同属性的对象。

1.Collection

1、一个java.util 包下的集合接口,是List、Set和Queue接口的父接口;

2、定义了可用于操作List、Set和Queue的方法——增删改查;

3.存储一组不唯一,无序的对象;

1.list

存储一组不唯一,有序的对象

方法:

1.boolean add(Object o) 在列表的末尾添加元素

2.void add(int index,Object o)在指定的索引位置添加元素

3.int size()返回列表中元素的个数

4.get(int index)返回指定索引位置处的元素。取出的元素是Object类型,使用前需要进行强制类型转换

5.contains(Object o)判断列表中是否存在指定元素

6.remove(Object o)从列表中删除指定位置元素

7.remove(int index)从列表中删除指定位置元素,从0开始检索。

1.ArrayList

顺序表,又叫做数组序列,list的一个实现类,方便查询与检索

2.LinkedList

采用链表存储方式。对于经常插入和删除的数据管理效率较高

2.set

存储一组唯一,无序的对象

1.HashSet

常用 add(),remove(),size()

 Set set = new HashSet();
        String str1 = "java";
        String str2 = "java2";
        String str3 = "java3";
        set.add(str1);
        set.add(str2);
        set.add(str3);
        Iterator iterator = set.iterator();  // 迭代器
        while (iterator.hasNext()){
            String str = (String)iterator.next();
            System.out.println(str);
        }

2.TreeSet

2.Map

  • Map提供了一种映射关系,元素是以键值对(key-value)的形式存储的,能根据key快速查找value;

  • Map中的键值对以Entry类型的对象实例形式存在;

  • key值不能重复,value值可以重复;

  • key对value是多(一)对一的关系;

  • Map接口提供了返回key值集合、value值集合、Entry值集合的方法;

  • Map支持泛型,形式如:Map<K,V>

    方法:

  • remove(Object key) 删除键值对应得数据

  • put(Object key, Object value) 存入键值对

  • get(Object key)得到对应键值对

  • Int size() 返回元素个数

  • Set keySet()返回键的集合

  • Collection values()返回值的集合

  • Set entrySet()返回键值对的集合

  • containsKey(Object key)比较对应键值是否存在,存在返回true

1.HashMap
  • HashMap是Map的一个重要实现类,也是最常用的,基于哈希表实现;

  • HashMap中的Entry对象是无序排列的;

  • Key值和value值都可以为null,但是一个HashMap只能有一个Key值为null的映射(Key值不可重复);

    public class MapTest {
        public static void main(String[] args) {
            Map<String,String> map = new HashMap<String,String>();
            map.put("student","学生");
            map.put("moon","月亮");
            map.put("people","人");
            Set set = map.keySet();
            Iterator iterator = set.iterator();   // 输出键值
            while (iterator.hasNext()){
                System.out.println(iterator.next());
            }
            System.out.println("**************************************");
            Collection collection = map.values();  // 输出值
            for (Object obj : collection){
                System.out.println(obj);
            }
            boolean flag = map.containsKey("moon");  // 比较是否存在键值
            System.out.println(flag);
            System.out.println(map.containsValue("学生")); // 比较是否存在值
             Set<Map.Entry<String, String>> entries = map.entrySet(); // 返回一个键值对
            Iterator<Map.Entry<String, String>> iterator1 = entries.iterator(); //使用迭代器
            while (iterator1.hasNext()){
                Map.Entry<String,String> entry = iterator1.next(); 
                System.out.println(entry.getKey()+"\t"+entry.getValue()); //返回对应得键值对
        }
    }
    
2.TreeMap

3.迭代器

iterator

 Iterator iterator = set.iterator();  // 迭代器
        while (iterator.hasNext()){
            String str = (String)iterator.next(); // 强制转换类型
            System.out.println(str);
        }

4.泛型

用于表明返回值类型,在输出时不用在强制类型转换。

        List<Penguin> list = new ArrayList<Penguin>(); // 构造一个列表,泛型表明类型
		// <E>里面的为泛型的类型

十.IO流

1.File类

1.java.io.File
 //假设文件在D盘files目录下,文件名叫Hello.txt
        File file = new File("D:\\files\\Hello.txt");
        File file1 = new File("D:/files/Hello.txt");
        File file2 = new File("D:\\files", "Hello.txt");
        
2.文件类的方法

1.boolean exists() 判断是否存在文件或者目录

2.boolean isFile() 判断是否是文件

3.boolean isDirectory() 判断是否是目录

4.String getPath() 返回此对象表示的文件的相对路径名

5.String getAbsolutePath() 返回此对象表示的文件的绝对路径名

6.String getName() 返回此对象表示的文件或目录的名称

7.boolean delete() 删除此对象指定的文件或目录

8.boolean createNewFile() 创建名称的空文件,不创建文件夹

9.long length() 返回文件的长度,单位为字节,如果文件不存在,则返回OL

//假设文件在D盘files目录下,文件名叫Hello.txt
        File file = new File("D:\\java\\Hello.txt");
        boolean exists = file.exists(); // 判断是否存在文件
        System.out.println("是否存在文件"+exists);
        System.out.println("文件名称为:"+file.getName()); // 返回文件名称
        String path = file.getPath();  // 获得相对地址
        System.out.println("相对地址为:"+path);
        System.out.println("绝对地址为:"+file.getAbsoluteFile()); // 获得绝对地址
        boolean delete = file.delete();
        System.out.println("删除了吗:"+delete);
        File file1 = new File("D:/java/hello.txt"); // 新文件的地址
        try {
            file1.createNewFile(); // 创建新文件
        }catch (IOException e){
            System.out.println("有问题");
        }
        long length = file.length();
        System.out.println("创建的文件长度为:"+length);
        boolean exists1 = file1.exists();
        System.out.println("新建文件是否存在"+exists1);
        System.out.println("新文件是否是目录"+file1.isDirectory());

2.输入输出流

流是指一连串的字符,是以先进先出方式发送信息的通道

输入流:往内存读入的数据———读

输出流:往文件写入的数据——-—写

四个基类:

1.Reader (字符流输入流)
2.Writer (字符流输出流)
3.InputStream (字节流输入流)
4.OutputStrean (字节流输出流)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PUOmmPt8-1663330627377)(D:\学习文档\Java\屏幕截图 2021-12-07 232946.png)]

InputStream(输入流)
子类:FileInputStream重点
构造FileInputStream对象:FileInputStream fileInputStream = new FileInputStream(String filePath);
FileInputStream fileInputStream = new FileInputStream(File file);
FilterInputSteam
子子类:BufferedInputStream重点(缓冲区输入流)
DataInputStream 二进制文件的读

DataInputStream datainputStream = new DatainputStream(InputStream inputStream);

public static void main(String[] args) throws IOException {
        // 构造文件输入流
        FileInputStream fileInputStream = new FileInputStream("C:\\top.bmp");
        // 构造二进制输入流
        DataInputStream dataInputStream = new DataInputStream(fileInputStream);
        // 构造文件输出流
        FileOutputStream fileOutputStream = new FileOutputStream("D:\\myDoc\\myPicture.bmp");
        // 输出文件
        DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
        byte[] file = new byte[1024];
        System.out.println("开始输入!");
        while (dataInputStream.read(file) != -1){
            dataOutputStream.write(file);
        }
        System.out.println("输入成功,结束输出!");
        // 关闭输入流
        dataInputStream.close();
        dataInputStream.close();
    }

InPutStream方法:

int read()

int read (byte[] b)

int read(byte[] b,int off,int len)

void close()

int available()

FileInputStream常用构造方法

1.FileInputStream(File file)

2.FileInputStream(String name)


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputDemo {
    public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream = new FileInputStream("D:\\java\\hello.txt");
        byte[] bytes = new byte[1024]; // 字节数组
        int len = 0;
        while (len != -1){
            len = fileInputStream.read(bytes,0,2); // 读入字节
            System.out.print(len);
        }
        fileInputStream.close();
    }
}

OutputStream
子类:FileOutputStream重点
构造FileOutputStream对象:FileOutputStream fileOutputStream = new FileOutputStream(String filePath);
FileOutputStream fileOutputStream = new FileOutputStream(File file);
FileOutputStream fileOutputStream = new FileOutputStream(String filePath, boolean append);

​ DataOutputStream 二进制文件的写

OutputStream方法:

void write(int c)

void write(byte[] buf)

void write(byte[] b,int off,int len)

void close()

FileOutputStream常用构造方法:

FileOutputStream(Filen file)

FileOutputStream(String name)

FileOutputStream(String name,boolean append)

append:(是否追加)


import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class FileOutputDemo {
    public static void main(String[] args) throws IOException {
        File file = new File("D:\\java\\test.txt");
        FileOutputStream fileOutputStream = new FileOutputStream(file,true); // append 表示是否覆盖,TRUE表示追加
        String str = "我要好好学习鸭!";
        byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
        fileOutputStream.write(bytes,0,bytes.length);
        fileOutputStream.close();
    }
}

读写文件的通用步骤(普适性的做法)
第一步:引入相关类
第二步:构造输入流对象或输出流对象
第三步:读文件或写文件操作————read()或write()————字节流 -1 字符流 null
第四步:关闭流————close()

Reader
子类:InputStreamReader重点
BufferedReader (带有缓冲区的流)

构造BufferedReader对象:BufferedReader bufferedReader = new BufferedReader(Reader reader);
BufferedReader特有的方法readLine();

eg:


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class BufferReaderDemo {
    public static void main(String[] args) throws IOException {
        FileReader fileReader = new FileReader("D:\\java\\hello.txt");
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        System.out.println(bufferedReader.readLine());
    }
}

子子类:FileReader重点
构造FileReader对象:FileReader fileReader = new FileReader(String filePath);
FileReader fileReader = new FileReader(File file);

public static void main(String[] args) throws IOException {
        // FileReader 读文件
        // 构造FileReader对象
            FileReader fileReader = new FileReader("D:\\java\\hello.txt");
           //读文件
           int len = 0;
           while (len != -1){
               len = fileReader.read();
               System.out.print((char)len);
           }
    }

Writer
子类:OutputStreamWriter重点
子类的子类:FileWriter重点
构造FileWriter对象:FileWriter fileWriter = new FileWriter(String filePath);
FileWriter fileWriter = new FileWriter(File file);

BufferedWriter(带有缓冲区的写)

方法: flash()强制刷新缓存

BufferedWriter bufferedReader = new BufferedReader(Reader reader)

3.节点流

CharArrayReader,Writer,inputstream,outputstream

StringReader,Writer

pipe(管道流) pipedOutputStream

4.处理流

1.buffer

bufferInputStream

bufferOutputStream

bufferReader

bufferWriter

序列化 反序列化 Serializable transient(透明的)

2.data

DataInputStream

DataOutputStream

3.转换流

InputStreamReader

outputStreamWriter

4.Filter

四个

5.print

printWriter

PrintStream

十一.JDBC

1.MySQL安装

步骤:

1.MySQL8.0 For Windows zip包下载地址:https://dev.mysql.com/downloads/file/?id=476233,进入页面后可以不登录。后点击底部“No thanks, just start my download.”即可开始下载。

2.安装:

*解压zip包到安装目录*

我的是:E:\MySQL8.0\mysql\bin

3.创建配置文件my.ini:

在Windows系统中,配置文件默认是安装目录下的 my.ini 文件(或my-default.ini),部分配置需要在初始安装时配置,大部分也可以在安装完成后进行更改。当然,极端情况下,所有的都是可以更改的。

我们发现解压后的目录并没有my.ini文件,没关系可以自行创建。在安装根目录下添加 my.ini,比如我这里是:E:\MySQL8.0\mysql\my.ini,写入基本配置:

/*
[mysqld]
# 设置3306端口
port=3306
# 设置mysql的安装目录
basedir=E:\MySQL8.0\mysql\bin
# 设置mysql数据库的数据的存放目录
datadir=E:\MySQL8.0\mysql\data
# 允许最大连接数
max_connections=200
# 允许连接失败的次数。这是为了防止有人从该主机试图攻击数据库系统
max_connect_errors=10
# 服务端使用的字符集默认为UTF8
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
# 默认使用“mysql_native_password”插件认证
default_authentication_plugin=mysql_native_password
[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8
[client]
# 设置mysql客户端连接服务端时默认使用的端口
port=3306
default-character-set=utf8
*/

4.在MySQL安装目录的 bin 目录下执行命令:

*mysqld --initialize --console*

执行完成后,会打印 root 用户的初始默认密码,比如:

C:\Users\Administrator>cd C:\Program Files\MySQL\bin

C:\Program Files\MySQL\bin>mysqld --initialize --console

2018-04-28T15:57:17.087519Z 0 [System] [MY-013169] [Server] C:\Program Files\MySQL\bin\mysqld.exe (mysqld 8.0.11) initializing of server in progress as process 4984

2018-04-28T15:57:24.859249Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: rI5rvf5x5G,E

2018-04-28T15:57:27.106660Z 0 [System] [MY-013170] [Server] C:\Program Files\MySQL\bin\mysqld.exe (mysqld 8.0.11) initializing of server has completed

C:\Program Files\MySQL\bin>

注意!执行输出结果里面有一段: [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: rI5rvf5x5G,E 其中root@localhost:后面的“rI5rvf5x5G,E”就是初始密码(不含首位空格)。在没有更改密码前,需要记住这个密码,后续登录需要用到。

要是你手贱,关快了,或者没记住,那也没事,删掉初始化的 datadir 目录,再执行一遍初始化命令,又会重新生成的。当然,也可以使用安全工具,强制改密码,用什么方法,自己随意。

参考:https://dev.mysql.com/doc/refman/8.0/en/data-directory-initialization-mysqld.html

5.安装服务:

在MySQL安装目录的 bin 目录下执行命令(以管理员身份打开cmd命令行,或者在安装目录Shift+右键“在此处打开命令行窗口”):

*mysqld --install [服务名]*

后面的服务名可以不写,默认的名字为 mysql。当然,如果你的电脑上需要安装多个MySQL服务,就可以用不同的名字区分了,比如 mysql5 和 mysql8。

安装完成之后,就可以通过命令****net start mysql****启动MySQL的服务了。

示例:


C:\Program Files\MySQL\bin>mysqld --install
Service successfully installed.

C:\Program Files\MySQL\bin>net start mysql
MySQL 服务正在启动 ..
MySQL 服务已经启动成功。


C:\Program Files\MySQL\bin>

2.更改密码和密码认证插件

在MySQL安装目录的 bin 目录下执行命令:

*mysql -u root -p*
  这时候会提示输入密码,记住了上面第1.3步安装时的密码,填入即可登录成功,进入MySQL命令模式。

在MySQL8.0.4以前,执行

SET PASSWORD=PASSWORD(‘[修改的密码]’);
就可以更改密码,但是MySQL8.0.4开始,这样默认是不行的。因为之前,MySQL的密码认证插件是“mysql_native_password”,而现在使用的是“caching_sha2_password”。

因为当前有很多数据库工具和链接包都不支持“caching_sha2_password”,为了方便,我暂时还是改回了“mysql_native_password”认证插件。

修改用户密码,在MySQL中执行命令:

*ALTER USER ‘root’@‘localhost’ IDENTIFIED WITH mysql_native_password BY ‘新密码’;*
修改密码验证插件,同时修改密码。

如果想默认使用“mysql_native_password”插件认证,可以在配置文件中配置default_authentication_plugin项。

*[mysqld]*
*default_authentication_plugin=mysql_native_password*

示例:

C:\Program Files\MySQL\bin>mysql -u root -p
Enter password: ************
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.11

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密码';
Query OK, 0 rows affected (0.06 sec)

mysql>

3.mysql的简单操作:

可以用 命令查看一下默认安装的数据库:

show databases; 查看所有数据库

use mysql;使用某一数据库

show tables;查看所有表

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.01 sec)

mysql>

看到默认初始化了mysql数据库,其中user表里面存储MySQL用户信息。我们可以看一下默认MySQL用户:

select user,host,authentication_string from mysql.user;

mysql> select user,host,authentication_string from mysql.user;
+------------------+-----------+-------------------------------------------+
| user             | host      | authentication_string                     |
+------------------+-----------+-------------------------------------------+
| mysql.infoschema | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| mysql.session    | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| mysql.sys        | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| root             | localhost | *27C237A977F4F44D3F551F1A673BE14DFD232961 |
+------------------+-----------+-------------------------------------------+
4 rows in set (0.00 sec)

mysql>

管理员root的host是localhost,代表仅限localhost登录访问。如果要允许开放其他ip登录,则需要添加新的host。如果要允许所有ip访问,可以直接修改成“*%*

创建用户:

*CREATE USER ‘xxh’@‘%’ IDENTIFIED WITH mysql_native_password BY ‘xxh123!@#’;*

#(需要注意:mysql8.0加密方式修改了)
#检查用户

*select user, host, plugin, authentication_string from user\G;*

授权远程数据库

#授权所有权限
*GRANT ALL PRIVILEGES ON *.* TO ‘xxh’@‘%’;*
#授权基本的查询修改权限,按需求设置
*GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER ON *.* TO ‘xxh’@‘%’;*

查看用户权限
*show grants for ‘xxh’@‘%’;*

示例:


mysql> use mysql;
Database changed
mysql> CREATE USER 'xxh'@'%' IDENTIFIED WITH mysql_native_password BY 'xxh123!@#'; #创建用户(注意:mysql8.0加密方式修改了)
Query OK, 0 rows affected (0.07 sec)
mysql> 

 

4.增删查改

1.以管理员身份运行命令提示符

mysql -uroot -proot

如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0BWw4vv4-1663330627378)(C:\Users\yangxing\Pictures\mysql\屏幕截图 2021-12-11 003140.png)]

2.通过show databases 查看所有数据库:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Lq5SBd9-1663330627379)(C:\Users\yangxing\Pictures\mysql\屏幕截图 2021-12-11 003303.png)]

3.通过Create来创建表,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BrVAHwqg-1663330627380)(C:\Users\yangxing\Pictures\mysql\屏幕截图 2021-12-11 003549.png)]

4.通过show tables 查看表:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wuf9kDgt-1663330627380)(C:\Users\yangxing\Pictures\mysql\屏幕截图 2021-12-11 003719.png)]

5.通过Insert语句来插入表数据,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ZBI4ay2-1663330627381)(C:\Users\yangxing\Pictures\mysql\屏幕截图 2021-12-11 003838.png)]

6.通过Select来查询表中数据,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CiixAnxq-1663330627381)(C:\Users\yangxing\Pictures\mysql\屏幕截图 2021-12-11 003930.png)]

7.通过Update来更新表中数据,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cit46zeo-1663330627382)(C:\Users\yangxing\Pictures\mysql\屏幕截图 2021-12-11 004031.png)]

8.通过Delete来删除表中数据,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JROh8MnC-1663330627382)(C:\Users\yangxing\Pictures\mysql\屏幕截图 2021-12-11 004133.png)]

5.关闭数据库连接:

net stop mysql

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cVmr74vb-1663330627383)(C:\Users\yangxing\Pictures\mysql\屏幕截图 2021-12-11 004617.png)]

6.下载mysql驱动:

mySQL连接驱动下载

选择Platform Independent

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NHgmDLmF-1663330627383)(https://img.jbzj.com/file_images/article/202104/2021040710465940.png)]

点击Download

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pIyqPWEa-1663330627384)(https://img.jbzj.com/file_images/article/202104/2021040710465941.png)]

点击No thanks, just start my download.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jQpBDo6J-1663330627385)(https://img.jbzj.com/file_images/article/202104/2021040710465942.png)]

自动开始下载

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N6RN8WXr-1663330627385)(https://img.jbzj.com/file_images/article/202104/2021040710465943.png)]

解压ZIP,复制出mysql-connector-java-8.0.23.jar文件(选择自己想要放入的路径)

7.连接mysql:

先将驱动包导入到项目外部资源中:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nBwl5qph-1663330627385)(C:\Users\yangxing\Pictures\mysql\屏幕截图 2021-12-11 005142.png)]

代码连接:


import java.sql.*;

public class Jdbc {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.cj.jdbc.Driver");  // 加载驱动
        Connection con; //创建连接对象
        Statement stmt; //创建与数据库交互
        // 定义用户名及密码
        String user = "root";
        String password = "926456";
        // 数据库URL
        String url = "jdbc:mysql://localhost:3306/educ?characterEncoding=utf-8&rewriteBatchedStatement=true,useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";
        System.out.println("连接数据库...");
        con = DriverManager.getConnection(url,user,password); // 打开链接
        // 执行查询
        System.out.println("实例化Statement对象...");
        stmt = con.createStatement();
        String sql;
        sql = "SELECT * FROM student";
        ResultSet rs = stmt.executeQuery(sql);
        // 展开结果数据库
        while (rs.next()){
            // 通过字段检索
            String sno = rs.getString("sno");
            String sname = rs.getString("sname");
            int sage = rs.getInt("sage");
            //输出数据
            System.out.print("sno:"+sno);
            System.out.print(",sname:"+sname);
            System.out.print(",sage:"+sage);
            System.out.println();
        }
        //完成后逐个关闭
        rs.close();
        stmt.close();
        con.close();
        System.out.println("连接数据库结束!");
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Iq2h3XVr-1663330627386)(C:\Users\yangxing\Pictures\mysql\屏幕截图 2021-12-11 005314.png)]

JDBC API提供的主要操作:
1 Java程序 跟 数据库 连接;
2 通过Java程序可以对数据库的数据表的数据增、删、改、查
3 处理执行结果

步骤(共五步骤):
1加载驱动
2建立连接
3发送语句
4返回结果
5释放资源

8.mysql远程登录权限配置:

MySQL数据库远程访问权限 Linux
JDBC操作工具类

mysql -u root -p

use mysql;

grant all privileges on . to ‘root’@‘%’;

错误You are not allowed to create a user with grant
执行update user set host=‘%’ where user=‘root’;

flush privileges;

9.用java进行数据库的查询与更新


import java.sql.*;

public class Homework22 {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        // 1.加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection con = null;
        Statement statement = null;
        ResultSet rs = null;
        // 定义URL及用户名密码
        String url = "jdbc:mysql://localhost:3306/educ?";
        String user = "root";
        String password = "926456";
        String sql;
        // 2.建立连接
        try {
            con = DriverManager.getConnection(url, user, password);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            System.out.println("URL或用户名及密码错误");
        }
        String recording = "('001','张三','北京','2',8000)," +  // 三条记录
                "('002','李四','上海','3',9000),('003','王五','广州','3',8500)";
        sql = "insert into Employee values" + recording;
        // 3.发送语句
        statement = con.createStatement();
        int alter = 0;
        try {
            alter = statement.executeUpdate(sql);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            System.out.println("插入失败");
        }
        // 4.返回结果
        System.out.println("插入成功" + alter);
        //查询张三的信息:
        try {
            rs = statement.executeQuery("select * from employee where name = '张三'");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            System.out.println("没有查询到!");
        }
        System.out.println("张三的信息为:");
        while (rs.next()) {
            String id = rs.getNString("id");
            String position = rs.getNString("position");
            String name = rs.getNString("name");
            int holiday = rs.getInt("holiday");
            int salary = rs.getInt("salary");
            System.out.println("id:" + id + '\t' + "name:" + name + '\t' + "position:"
                    + position + '\t' + "holiday:" + holiday + '\t' + "salary:" + salary);
        }
        // 5.释放资源
        rs.close();
        statement.close();
        con.close();
    }
    }

十二.网络编程

1.InetAddress 类

 public static void main(String[] args) throws UnknownHostException {
        // 查询本机地址
        InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1"); // 得到本地名
        System.out.println(inetAddress1);
        InetAddress inetAddress2= InetAddress.getByName("localhost"); //得到本地主机号
        System.out.println(inetAddress2);
        InetAddress inetAddress3 = InetAddress.getLocalHost(); //得到本地主机号
        System.out.println(inetAddress3);
        // 查询网站地址
        InetAddress inetAddress4 = InetAddress.getByName("www.baidu.com"); // 得到该域名号
        System.out.println(inetAddress4);
        System.out.println(inetAddress4.getCanonicalHostName()); // 规范名
        System.out.println(inetAddress4.getHostAddress());
        System.out.println(inetAddress4.getHostName());
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x4LTxBRQ-1663330627386)(C:\Users\yangxing\Pictures\mysql\屏幕截图 2021-12-12 210211.png)]

2.端口port

端口表示计算机上的一个程序的进程

不同的进程有不同的端口:0~65536

公有端口:0~1023

TCP:80,HTTP:80,HTTPS:43,FTP:21,TELNET:23

程序注册端口:1024~49151

Tomcat:8080,MySQL:3306,Oracle:1521

3.通信协议

TCP/IP协议族

IP:网络层协议

4.TCP

传输控制协议(三次握手,四次挥手)

面向连接的,可靠的,基于字节流的传输通信协议

1.Socket

2.ServerSocket

客户端

1.连接服务器Socket,全双工的通信模型

2.打开Socket关联的输入输出流

3.数据流中读写信息

4.关闭所有的数据流和Socket


public class ClientTest {   // 客户端向服务器发送的数据
    public static void main(String[] args) {
        // 建立连接
        try {
            Socket socket = new Socket("127.0.0.1", 8090);
            // 打开输入输出流
            OutputStream os = socket.getOutputStream();
            // 发送客户端登录信息,即向输出流写入信息
            String info = "用户名:Tom;用户密码:123456";
            os.write(info.getBytes());
            // 关闭资源
            os.close();
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

服务端

1.建立服务的端口ServerSocket

2.等待用户的连接accpet

3.接受用户的消息


public class ServerTest {  // 接收客户端发送的数据
    public static void main(String[] args) {
        // 建立服务器Socket,指定端口开始监听
        try {
            ServerSocket serverSocket = new ServerSocket(8090);
            // 使用accept()方法等待客户端触发通信
            Socket socket = serverSocket.accept();
            // 打开输入输出流
            InputStream is = socket.getInputStream();
            // 获取客户端信息,即从输入输出流读取信息
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String info = null;
            while ((info= br.readLine())!=null){
                System.out.println("我是服务器,客户登录信息为:"+info);
            }
            // 关闭资源
            br.close();
            is.close();
            socket.close();
            serverSocket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

5.UDP

1.DatagramPacket

负责数据打包,负责数据解包

2.DatagramSocket

负责发送数据,负责接收数据

用户数据报协议

无连接的协议,在传输数据之前,客户端和服务器并不建立和维护连接


import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
//不需要连接服务器
public class UDPClient {
    public static void main(String[] args) throws Exception{
        //1.建立一个Socket
        DatagramSocket socket = new DatagramSocket();
        //2.建个包
        String msg = "你好!服务器";
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 9090;
        //数据,数据的起始长度,要发送给谁
        DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length,
                localhost, port);
        //3.发送包
        socket.send(packet);
        //4.关闭流
        socket.close();
    }


import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UDPServers {
    public static void main(String[] args) throws Exception{
        // 开放端口
        DatagramSocket socket = new DatagramSocket(9090);
        // 接收数据包
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
        socket.receive(packet);// 阻塞接收
        System.out.println(packet.getAddress().getHostAddress());//得到地址
        System.out.println(new String(packet.getData(),0, packet.getLength()));

        //关闭连接
        socket.close();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9ZQ5aLB8-1663330627387)(C:\Users\yangxing\AppData\Roaming\Typora\typora-user-images\image-20211213104718127.png)]

6.URL

统一资源定位符,访问web必须用到的

十三.多线程

一个进程中同时运行了多个线程,用来完成不同的工作,称之为“多线程”

优点:简化编程模型,充分利用CPU的资源

start与run的区别:

调用start()方法会创建一个新的子线程并启动

调用run()方法只是Thread的一个普通方法调用

1.Thread类

一、继承Thread类创建线程类

(1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。
(2)创建Thread子类的实例,即创建了线程对象。
(3)调用线程对象的start()方法来启动该线程。

/**总结:
 * 创建线程一:继承Thread类,重写run()方法,调用start开启线程
 * 线程开启不一定立即执行,由CPU调度
*/
public class TestThread extends Thread{
    @Override
    public void run() {
       //run方法线程体
        for (int i = 0; i < 20; i++) {
            System.out.println("我在看代码-"+i);
        }
    }

    public static void main(String[] args) {
        //main线程,主线程
        // 创建一个线程对象
        TestThread testThread = new TestThread();
        // 调用start()方法开启线程
        testThread.start();
        for (int i = 0; i < 20; i++) {
            System.out.println("我在学习多线程-"+i);
        }
    }
}

start0,本地方法:java无权调用,交给底层的c处理 private native void start0();

2.Runnable接口

函数式接口 lambda表达式

二、通过Runnable接口创建线程类

(1)定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。
(2)创建 Runnable实现类的实例,并依此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
(3)调用线程对象的start()方法来启动该线程。


public class TestThread2 implements Runnable{
    @Override
    public void run() {
        //run方法线程体
        for (int i = 0; i < 20; i++) {
            System.out.println("我在看代码-"+i);
        }
    }

    public static void main(String[] args) {
        //main线程,主线程
        // 创建一个线程对象 ,调用start()方法开启线程
        TestThread2 testThread2 = new TestThread2();
        new Thread(testThread2).start();

        for (int i = 0; i < 20; i++) {
            System.out.println("我在学习多线程-"+i);
        }
    }
}

3.方法

setPriority(int newPriority) 更改线程的优先级

static void sleep(long millis)在指定的毫秒数内让当前正在执行的线程休眠

void join()等待该线程终止

static void yield()暂停当前正在执行的线程对象,并执行其他线程

void interrupt()中断线程

boolean isAlive()测试线程是否处于活动状态

eg:


public class ThreadGame2 implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+":hello"+i+"");
        }
    }

    public static void main(String[] args) {
        ThreadGame2 game2 = new ThreadGame2();
        Thread test1 = new Thread(game2, "test1");
        Thread test2 = new Thread(game2, "test2");
        test1.setPriority(Thread.MAX_PRIORITY);
        test2.setPriority(6);
        test1.start();
        test2.start();
    }
}

// join方法
public class ThreadGame implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("瞅你咋地");
        }
    }

    public static void main(String[] args) {
        ThreadGame threadGame = new ThreadGame();
        Thread thread = new Thread(threadGame);
        thread.setName("test");
        thread.start();
        for (int i = 1; i <=20; i++) {
            try {
                if (i==5) {
                    thread.join();  // 强制执行此线程,直至结束
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(thread.getName());
        }
    }
}

同步抢票:

// 同步抢票
public class MyThread implements Runnable {
    int total = 10; // 总共有十张票
    int num = 0; // 初始抢到票数为零

    @Override
    public void run() {
        while (total>0) {
            num++;
            total--;
            // 同步块
            synchronized (this) {
                if (Thread.currentThread().getName().equals("黄牛党")){
                    System.out.println(Thread.currentThread().getName() + "抢到第" + num + "张票,剩余" + total + "张票!");
                    return;
                }
            }
            System.out.println(Thread.currentThread().getName() + "抢到第" + num + "张票,剩余" + total + "张票!");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}


public class Homework25 {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        Thread thread1 = new Thread(myThread, "桃跑跑");
        Thread thread2 = new Thread(myThread, "张票票");
        Thread thread3 = new Thread(myThread, "黄牛党");
        thread1.start();
        thread2.start();
        thread3.start();
    }

}

4.Callable

可以有返回值

5.静态代理

new Thread(Runnable).start();

6.lambda表达式

函数式编程,避免内部类定义过多

new Thread(()->{

System.out.println();

}).start();

7.线程的状态

新建状态,运行,阻塞,死亡

8.线程同步

多个对象操作同一个资源,并发

队列+锁

Synchronized:

同步方法 弊端:锁太多了

同步代码块(常用!)

第一个线程进来拿到锁,后面就要排队了,直到这个人释放锁,后面拿到锁才能进去

**死锁:**两个人都抱着对方的锁

必要条件:1.互斥2.请求与保持3.不可剥夺条件4.循环等待条件

9.Lock(优先级高)

ReentrantLock lock,trylock,unlock

10.线程通信

1.缓冲区:消息队列
2.标志位:(红绿灯)
3.wait();
4.notifyAll();

11.线程池

1.池化技术
2.池的大小
3.最大连接数
4.保持时间

十四.GUI(可选)

1.AWT

1.Frame
2.监听事件

鼠标,键盘,窗口,动作事件

2.Swing

文本框,标签,按钮,文本域,面板,布局方式,关闭窗口,列表

3.贪吃蛇小游戏

1.Timer
2.键盘监听
3.游戏帧的概念

十五.注解

1.Annotation的作用:

(1)不是程序本身,可以对程序作出解释。(这一点和注释(comment)没什么区别)

(2)可以被其他程序(比如:编译器等)读取

2.Annotation的格式:

(1)注解是以“@注释名”在代码中存在的,还可以添加一些参数值,例如:@SuppressWarnings(value=“unchecked”).

3.Annotation在哪里使用?

可以附加在package,class,method,field等上面,相当于给他们添加了额外的辅助信息,我们可以通过反射机制编程实现对这些元数据的访问

4.注解有哪些:

一.内置注解:

(1)@Override:定义在java.lang.Override中,此注释只适用于修饰方法,表名一个方法声明打算重写超类中的另一个方法声明。

(2)**@Deprecated:**不推荐程序员使用,但是可以使用,或者存在更好的方式

(3)@SuppressWarnings:定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息。

与前两个注释有所不同,你需要添加一个参数才能正常使用,这些参数都是已经定义好了的,我们选择性的使用就好了

@SuppressWarnings(“all”)

@SuppressWarnings(“unchecked”)

@SuppressWarnings(value={“unchecked”,“deprecation”})

等等

二.元注解

1.元注解的作用就是负责注解其他注解,java定义了4个标准的meta-annotation类型,他们被用来提供对其他annotation类型作说明

2.这些类型和他们所支持的类在java.lang.annotation包中可以找到。(@Target,@Retention,@Documemnted,@Inherited)

@Target:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)

@Retention:表示需要在什么级别保存该注释信息,用于描述注解的生命周期

(SOURCE<CLASS<RUNTIME

@Document:说明该注解将被包含在javadoc中

@Inherited:说明子类可以继承父类中的该注解

三.自定义注解:

使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口

分析:

1.@interface用来声明一个注解,格式:public @interface 注解名{定义内容}

2.其中的每一个方法实际上是声明了一个配置参数。

3.方法的名称就是参数的名称。

4.返回值类型就是参数的类型(返回值只能是基本类型,Class,String,enum).

5.可以通过default来声明参数的默认值

6.如果只有一个参数成员,一般参数名为value

7.注解元素必须要有值,我们定义注解元素时,经常使用空字符串,0作为默认值。

// 元注解
@Target({ElementType.METHOD,ElementType.TYPE}) //作用范围
@Retention(RetentionPolicy.RUNTIME) //作用周期
// 自定义注解
@interface MyAnnotation2{
    //注解的参数:参数类型 + 参数名();
    String name() default "";  // 有默认值
    int age() ; //必须在注解参数中定义
    String[] schools() default {"清华大学"};
}
//元注解
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
// 自定义注解
@interface MyAnnotation3{
    String value(); // 只有一个元素时
}
四.反射读取注解

十六.反射

1.反射定义:

1.Reflection(反射)是java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。

Class c = Class.forName(“java.lang.String”)

2.加载完类之后,在堆得方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类得结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们形象的称之为:反射

**正常方式:**引入需要的“包类名称” ———通过new实例化————取得实例化对象

**反射方式:**实例化对象————getClass()方法————得到完整的“包类”名称

2.Java反射机制提供的功能:

1.在运行时判断任意一个对象所属的类

2.在运行时构造任意一个类的对象

3.在运行时判断任意一个类所具有的成员变量和方法

4.在运行时获取泛型信息

5.在运行时调用任意一个对象的成员变量和方法

6.在运行时处理注解

7.生成动态代理

3.Javaa反射优点和缺点:

优点:

可以实现动态创建对象和编译,体现出很大的灵活性

缺点:

对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于直接执行相同的操作。

Class:

在Object类中定义了以下方法,此方法被所有子类继承

public final Class getClass()

以上的方法返回值的类型是一个Class类,此类是java反射的源头,实际上所谓反射从程序的运行结果来看也很好理解,即:可以通过对象反射求出类的名称。

3.获取Class的方法:


//测试class类的创建方式有哪些
public class Test03 {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Student();
        System.out.println("我是"+person.name);

        //方式一:通过对象获得
        Class c1 = person.getClass();
        System.out.println(c1.hashCode());

        //方式二:forName
        Class c2 = Class.forName("com.ChenXing.reflection.Student");
        System.out.println(c2.hashCode());

        //方式三:通过类名.class获得
        Class c3 = Student.class;
        System.out.println(c3.hashCode());

        //方式四:基本内置类型的包装类都有一个Type属性
        Class c4 = Integer.TYPE;
        System.out.println(c4);

        //获得父类类型
        Class c5 = c1.getSuperclass();
        System.out.println(c5);
    }
}


class Person{
    public String name;
}
class Student extends Person{
   public Student(){
       this.name = "学生";
   }
}

class Teacher extends Person{
    public Teacher(){
        this.name = "老师";
    }
}

4.哪些类可以有Class对象:

1.class:外部类,成员(成员内部类,静态局部类),局部内部类,匿名内部类。

2.interface:接口

3.[ ]:数组

4.enum:枚举

5.annotation:注解@interface

6.primitive type:基本数据类型

7.void


import java.lang.annotation.ElementType;

public class Test04 {
    public static void main(String[] args) {
        Class c1 = Object.class;  //类
        Class c2 = Comparable.class;//接口
        Class c3 = String[].class;//一维数组
        Class c4 = int[][].class;//二维数组
        Class c5 = Override.class;//注解
        Class c6 = ElementType.class;//枚举
        Class c7 = Integer.class;//基本数据类型
        Class c8 = void.class;//void
        Class c9 = Class.class;//Class
        //输出
        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c4);
        System.out.println(c5);
        System.out.println(c6);
        System.out.println(c7);
        System.out.println(c8);
        System.out.println(c9);

        //只要元素类型与维度一样,就是同一个Class.
        int[] a = new int[10];
        int[] b = new int[100];
        System.out.println(a.getClass().hashCode());
        System.out.println(b.getClass().hashCode());
    }
}

//运行结果如下:
class java.lang.Object
interface java.lang.Comparable
class [Ljava.lang.String;
class [[I
interface java.lang.Override
class java.lang.annotation.ElementType
class java.lang.Integer
void
class java.lang.Class
1836019240
1836019240

5.类加载器的作用:

类加载器作用是用来把类(class)装载进内存的。JVM规范定义了如下类型的类的加载器。


public class Test05 {
    public static void main(String[] args) throws ClassNotFoundException {

        //获取系统类的加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);

        //获取系统类加载器的父类加载器-->扩展类加载器
        ClassLoader parent = systemClassLoader.getParent();
        System.out.println(parent);

        //获取扩展类加载器的父类加载器-->根加载器(C/C++)
        ClassLoader parent1 = parent.getParent();
        System.out.println(parent1);

        //测试当前类是哪个加载器加载的
        ClassLoader classLoader = Class.forName("com.ChenXing.reflection.Test05").getClassLoader();
        System.out.println(classLoader);

        //测试JDK内置的类是谁加载的
        ClassLoader classLoader1 = Class.forName("java.lang.Object").getClassLoader();
        System.out.println(classLoader1);
    }
}

//运行结果
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@6d6f6e28
null
sun.misc.Launcher$AppClassLoader@18b4aac2
null

6.获得类的信息:


import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

//获得类的信息
public class Test06 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class c1 = Class.forName("com.ChenXing.reflection.USer");

        //获得类的名字
        System.out.println(c1.getName()); //获得包名 + 类名
        System.out.println(c1.getSimpleName()); //获得类名

        //获得类的属性
        System.out.println("=============================================");
        Field[] fields = c1.getFields(); //只能找到public属性

        fields = c1.getDeclaredFields(); //找到所有的属性
        for (Field field : fields){
            System.out.println(field);
        }

        //获得指定属性的值
        Field name = c1.getDeclaredField("name");
        System.out.println(name);

        //获得类的方法
        System.out.println("=============================================");
        Method[] methods = c1.getMethods();//获得本类及其父类的全部public方法
        for (Method method : methods) {
            System.out.println("正常的:"+method);
        }
        methods = c1.getDeclaredMethods();//获得本类的所有方法
        for (Method method : methods) {
            System.out.println("getDeclaredMethods:"+method);
        }

        //获得指定的方法
        System.out.println("=============================================");
        Method getName = c1.getMethod("getName", null);
        Method setName = c1.getMethod("setName", String.class);
        System.out.println(getName);
        System.out.println(setName);

        //获得构造器
        System.out.println("=============================================");
        Constructor[] constructors = c1.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        constructors = c1.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            System.out.println("所有的:"+constructor);
        }

        //获得指定构造器
        Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        System.out.println("指定的:"+declaredConstructor);
    }
}

//运行结果:
com.ChenXing.reflection.USer
USer
=============================================
private java.lang.String com.ChenXing.reflection.USer.name
private int com.ChenXing.reflection.USer.id
private int com.ChenXing.reflection.USer.age
private java.lang.String com.ChenXing.reflection.USer.name
=============================================
正常的:public java.lang.String com.ChenXing.reflection.USer.toString()
正常的:public java.lang.String com.ChenXing.reflection.USer.getName()
正常的:public int com.ChenXing.reflection.USer.getId()
正常的:public void com.ChenXing.reflection.USer.setName(java.lang.String)
正常的:public void com.ChenXing.reflection.USer.setAge(int)
正常的:public void com.ChenXing.reflection.USer.setId(int)
正常的:public int com.ChenXing.reflection.USer.getAge()
正常的:public final void java.lang.Object.wait() throws java.lang.InterruptedException
正常的:public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
正常的:public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
正常的:public boolean java.lang.Object.equals(java.lang.Object)
正常的:public native int java.lang.Object.hashCode()
正常的:public final native java.lang.Class java.lang.Object.getClass()
正常的:public final native void java.lang.Object.notify()
正常的:public final native void java.lang.Object.notifyAll()
getDeclaredMethods:public java.lang.String com.ChenXing.reflection.USer.toString()
getDeclaredMethods:public java.lang.String com.ChenXing.reflection.USer.getName()
getDeclaredMethods:public int com.ChenXing.reflection.USer.getId()
getDeclaredMethods:public void com.ChenXing.reflection.USer.setName(java.lang.String)
getDeclaredMethods:public void com.ChenXing.reflection.USer.setAge(int)
getDeclaredMethods:public void com.ChenXing.reflection.USer.setId(int)
getDeclaredMethods:public int com.ChenXing.reflection.USer.getAge()
=============================================
public java.lang.String com.ChenXing.reflection.USer.getName()
public void com.ChenXing.reflection.USer.setName(java.lang.String)
=============================================
public com.ChenXing.reflection.USer(java.lang.String,int,int)
public com.ChenXing.reflection.USer()
所有的:public com.ChenXing.reflection.USer(java.lang.String,int,int)
所有的:public com.ChenXing.reflection.USer()
指定的:public com.ChenXing.reflection.USer(java.lang.String,int,int)

Process finished with exit code 0

7.获取类的运行时结构:

public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        //获得Class对象
        Class c1 = Class.forName("com.ChenXing.reflection.USer");

        //构造一个对象
        USer user = (USer)c1.newInstance(); //本质是调用了类的无参构造器
        System.out.println(user);

        //通过构造器创建对象
        Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        USer uSer = (USer) constructor.newInstance("辰星",001,21);
        System.out.println(uSer);

        //通过反射调用普通构造方法
        USer user3 = (USer) c1.newInstance();
        //通过反射获取一个方法
        Method setName = c1.getDeclaredMethod("setName", String.class);

        //invoke : 激活的意思
        //(对象,“方法的值”)
        setName.invoke(user3,"辰星");
        System.out.println(user3.getName());
        System.out.println("=============================================================");

        //通过反射操作属性
        USer user4 = (USer)c1.newInstance();
        Field name = c1.getDeclaredField("name");

        //不能直接操作私有属性,我们需要关闭程序的安全检测,属性或者方法的setAccessible(true)
        name.setAccessible(true);
        name.set(user4,"辰星2");
        System.out.println(user4.getName());
    }
}

//运行结果
USer{name='null', id=0, age=0}
USer{name='辰星', id=1, age=21}
辰星
=============================================================
辰星2

8.性能分析:


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test08 {
    //普通方式调用
    public static void test1() {
        USer uSer = new USer();
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            uSer.getName();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("普通方法执行10亿次时间:" + (endTime - startTime) + "ms");
    }

        //反射方式调用
        public static void test2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
            USer uSer = new USer();
            Class c1 = uSer.getClass();
            Method getName = c1.getDeclaredMethod("getName", null);
            long startTime = System.currentTimeMillis();
            for (int i = 0; i < 1000000000; i++) {
                getName.invoke(uSer,null);
            }
            long endTime = System.currentTimeMillis();
            System.out.println("反射方法执行10亿次时间:" + (endTime - startTime) + "ms");
        }

    //反射方式调用 关闭安全性检测
    public static void test3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        USer uSer = new USer();
        Class c1 = uSer.getClass();
        Method getName = c1.getDeclaredMethod("getName", null);
        getName.setAccessible(true);
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(uSer,null);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("关闭检测后执行10亿次时间:" + (endTime - startTime) + "ms");
    }

    public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
        test1();
        test2();
        test3();
    }
}

//运行结果
普通方法执行10亿次时间:5ms
反射方法执行10亿次时间:3980ms
关闭检测后执行10亿次时间:2142ms

9.反射获取泛型:


//通过反射获取泛型
public class Test09 {

    public void test1(Map<String, USer> map, List<USer> list) {
        System.out.println("test1");
    }

    public Map<String, USer> test2() {
        System.out.println("test2");
        return null;
    }

    public static void main(String[] args) throws NoSuchMethodException {
        Method method = Test09.class.getMethod("test1", Map.class, List.class);
        Type[] genericParameterTypes = method.getGenericParameterTypes();
        for (Type genericParameterType : genericParameterTypes) {
            System.out.println("泛型参数" + genericParameterType);
            if (genericParameterType instanceof ParameterizedType) {
                //得到真实参数类型
                Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
                for (Type actualTypeArgument : actualTypeArguments) {
                    System.out.println("得到真实参数类型" + actualTypeArguments);
                }
            }
        }
        method = Test09.class.getMethod("test2", null);
        Type genericReturnType = method.getGenericReturnType();
        if (genericReturnType instanceof ParameterizedType) {
            //得到真实返回值类型
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println("得到真实返回值类型" + actualTypeArguments);
            }
        }
    }
}

10.反射操作注解:


import java.lang.annotation.*;
import java.lang.reflect.Field;

//练习反射操作注解
public class Test10 {
}
@TableChen("db_student")
class student2{

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class c1 = Class.forName("com.ChenXing.reflection.student2");

        //通过反射获得注解
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }

        //获得注解的value的值
        TableChen tableChen = (TableChen) c1.getAnnotation(TableChen.class);
        String value = tableChen.value();
        System.out.println(value);

        //获得类指定的操作
        System.out.println("输出类指定注解:");
        Field name = c1.getDeclaredField("id");
        FieldChen annotation = name.getAnnotation(FieldChen.class);
        System.out.println(annotation.columnName());
        System.out.println(annotation.type());
        System.out.println(annotation.length());
    }
    @FieldChen(columnName = "db_id",type = "int",length = 10)
    private int id;
    @FieldChen(columnName = "db_age",type = "int",length = 10)
    private int age;
    @FieldChen(columnName = "db_name",type = "varchar",length = 3)
    private String name;
    public student2(){

    }

    public student2(int id, int age, String name) {
        this.id = id;
        this.age = age;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "student2{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

//类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableChen{
    String value();
}

//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldChen{
    String columnName();
    String type();
    int length();
}


//运行结果
@com.ChenXing.reflection.TableChen(value=db_student)
db_student
输出类指定注解
db_id
int
10

nType();
if (genericReturnType instanceof ParameterizedType) {
//得到真实返回值类型
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(“得到真实返回值类型” + actualTypeArguments);
}
}
}
}


### 10.反射操作注解:

```java

import java.lang.annotation.*;
import java.lang.reflect.Field;

//练习反射操作注解
public class Test10 {
}
@TableChen("db_student")
class student2{

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class c1 = Class.forName("com.ChenXing.reflection.student2");

        //通过反射获得注解
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }

        //获得注解的value的值
        TableChen tableChen = (TableChen) c1.getAnnotation(TableChen.class);
        String value = tableChen.value();
        System.out.println(value);

        //获得类指定的操作
        System.out.println("输出类指定注解:");
        Field name = c1.getDeclaredField("id");
        FieldChen annotation = name.getAnnotation(FieldChen.class);
        System.out.println(annotation.columnName());
        System.out.println(annotation.type());
        System.out.println(annotation.length());
    }
    @FieldChen(columnName = "db_id",type = "int",length = 10)
    private int id;
    @FieldChen(columnName = "db_age",type = "int",length = 10)
    private int age;
    @FieldChen(columnName = "db_name",type = "varchar",length = 3)
    private String name;
    public student2(){

    }

    public student2(int id, int age, String name) {
        this.id = id;
        this.age = age;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "student2{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

//类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableChen{
    String value();
}

//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldChen{
    String columnName();
    String type();
    int length();
}


//运行结果
@com.ChenXing.reflection.TableChen(value=db_student)
db_student
输出类指定注解
db_id
int
10
  • 6
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@辰星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值