Java进阶学习总结(网络编程、 类加载器、反射)

211 阅读14分钟

#博学谷IT学习技术支持#

10-1 网络编程

01-网络编程三要素-概述

  • 计算机网络

是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络 操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统

  • 网络编程

    • 在网络通信协议下,不同计算机上运行的程序,可以进行数据传输
  • IP地址

    • 是网络中设备的唯一标识
  • 端口

    • 端口号就可以唯一标识设备中的应用程序了。也就是应用程序的标识
  • 协议

    • 计算机网络连接和通信的规则被称为网络通信协议,它对数据的传输格式、传输速率、传输步骤等做了统一规定,通信双方必须同时遵守才能完成数据交换。
    • 常见的协议有UDP协议和TCP协议

02-网络编程三要素-IP

  • 是网络中设备的唯一标识

  • IP地址分为两大类

    • IPv4:是给每个连接在网络上的主机分配一个32bit地址。按照TCP/IP规定,IP地址用二进制来 表示,每个IP地址长32bit,也就是4个字节。 IP地址的这种表示法叫做“点分十进制表示法”
    • IPv6: 采用128位地址长度,每16 个字节一组,分成8组十六进制数
  • 特殊IP地址:

    • 127.0.0.1:是回送地址,可以代表本机地址,一般用来测试使用

03-网络编程-常见命令

ipconfig:查看本机IP地址

ping IP地址:检查网络是否连通

04-网络编程-Inetaddress类

InetAddress:此类表示Internet协议(IP)地址

05-网络编程三要素-端口

设备上应用程序的唯一标识

  • 端口号

    • 用两个字节表示的整数,它的取值范围是065535。其中,01023之间的端口号用于一些知名的网 络服务和应用,普通的应用程序需要使用1024以上的端口号。
    • 如果端口号被另外一个服务或 应用所占用,会导致当前程序启动失败

06-网络编程三要素-协议

计算机网络中,连接和通信的规则被称为网络通信协议

  • 协议

    • UDP协议 用户数据报协议(User Datagram Protocol)
    • UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接。简单来 说,当一台计算机向另外一台计算机发送数据时,发送端不会确认接收端是否存在,就会发 出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到数据。
    • 由于使用UDP协议消耗系统资源小,通信效率高,所以通常都会用于音频、视频和普通数据 的传输
    • 例如视频会议通常采用UDP协议,因为这种情况即使偶尔丢失一两个数据包,也不会对接收 结果产生太大影响。但是在使用UDP协议传送数据时,由于UDP的面向无连接性,不能保证数 据的完整性,因此在传输重要数据时不建议使用UDP协议
  • TCP协议

    • 传输控制协议 (Transmission Control Protocol)

    • TCP协议是面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再 传输数据,它提供了两台计算机之间可靠无差错的数据传输。在TCP连接中必须要明确客户端 与服务器端,由客户端向服务端发出连接请求,每次连接的创建都需要经过“三次握手”

    • 三次握手:TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连 接的可靠

      • 第一次握手,客户端向服务器端发出连接请求,等待服务器确认
      • 第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求
      • 第三次握手,客户端再次向服务器端发送确认信息,确认连接

10-2 UDP通讯程序

07-UDP-发送端

  • Java中的UDP通信

    • UDP协议是一种不可靠的网络协议,它在通信的两端各建立一个Socket对象,但是这两个
    • Socket只是发送,接收数据的对象,因此对于基于UDP协议的通信双方而言,没有所谓的客户 端和服务器的概念 Java提供了DatagramSocket类作为基于UDP协议的Socket
  • 构造方法

  • 相关方法

  • 发送数据的步骤

    • 创建发送端的Socket对象(DatagramSocket)
    • 创建数据,并把数据打包
    • 调用DatagramSocket对象的方法发送数据
    • 关闭发送端
  • 代码演示

  public class SendDemo {
      public static void main(String[] args) throws IOException {
          //创建发送端的Socket对象(DatagramSocket)
          // DatagramSocket() 构造数据报套接字并将其绑定到本地主机上的任何可用端口
          DatagramSocket ds = new DatagramSocket();
          //创建数据,并把数据打包
          //DatagramPacket(byte[] buf, int length, InetAddress address, int port)
          //构造一个数据包,发送长度为 length的数据包到指定主机上的指定端口号。
          byte[] bys = "hello,udp,我来了".getBytes();
          DatagramPacket dp = new DatagramPacket(bys,bys.length,InetAddress.getByName("127.0.0.1"),10086);
          //调用DatagramSocket对象的方法发送数据
          //void send(DatagramPacket p) 从此套接字发送数据报包
          ds.send(dp);
          //关闭发送端
          //void close() 关闭此数据报套接字
          ds.close();
      }
  }

08-UDP-接收端

  • 接收数据的步骤
    • 创建接收端的Socket对象(DatagramSocket)
  • 创建一个数据包,用于接收据
  • 调用DatagramSocket对象的方法接收数据
  • 解析数据包,并把数据在控制台显示
  • 关闭接收端
  • 构造方法

  • 相关方法

  public class ReceiveDemo {
      public static void main(String[] args) throws IOException {
            //创建接收端的Socket对象(DatagramSocket)
            DatagramSocket ds = new DatagramSocket(12345);
            //创建一个数据包,用于接收数据
            byte[] bys = new byte[1024];
            DatagramPacket dp = new DatagramPacket(bys, bys.length);
            //调用DatagramSocket对象的方法接收数据
            ds.receive(dp);
            //解析数据包,并把数据在控制台显示
            System.out.println("数据是:" + new String(dp.getData(), 0, dp.getLength()));
          }
      }
  }

10-UDP-三种通讯方式

  • 单播
    • 单播用于两个主机之间的端对端通信
  • 组播
    • 组播用于对一组特定的主机进行通信
  • 广播
    • 广播用于一个主机对整个局域网上所有主机上的数据通信

11-UDP-组播代码实现

实现步骤

  • 发送端

      1. 创建发送端的Socket对象(DatagramSocket)
      1. 创建数据,并把数据打包(DatagramPacket)
      1. 调用DatagramSocket对象的方法发送数据(在单播中,这里是发给指定IP的电脑但是在组 播当中,这里是发给组播地址)
      1. 释放资源
  • 接收端

      1. 创建接收端Socket对象(MulticastSocket)
      1. 创建一个箱子,用于接收数据
      1. 把当前计算机绑定一个组播地址
      1. 将数据接收到箱子中
      1. 解析数据包,并打印数据
      1. 释放资源
 组播报文的目的地址使用D类IP地址,224.0.0.0224.0.0.255
-    224.0.0.0224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;
-    224.0.1.0224.0.1.255是公用组播地址,可以用于Internet;
-    224.0.2.0238.255.255.255为用户可用的组播地址(临时组地址),全网范围内有效;
-    239.0.0.0239.255.255.255为本地管理组播地址,仅在特定的本地范围内有效。

12-UDP-广播代码实现

实现步骤

  • 发送端
      1. 创建发送端Socket对象(DatagramSocket)
      1. 创建存储数据的箱子,将广播地址(255.255.255.255) 封装进去
      1. 发送数据
      1. 释放资源
  • 接收端
      1. 创建接收端的Socket对象(DatagramSocket)
      1. 创建一个数据包,用于接收数据
      1. 调用DatagramSocket对象的方法接收数据
      1. 解析数据包,并把数据在控制台显示
      1. 关闭接收端

10-3 TCP通讯程序

13-TCP-客户端

  • Java中的TCP通信

    • Java对基于TCP协议的的网络提供了良好的封装,使用Socket对象来代表两端的通信端口,并通过Socket产生IO流来进行网络通信。
    • Java为客户端提供了Socket类,为服务器端提供了ServerSocket类
  • 构造方法

  • 相关方法

  public class ClientDemo {
      public static void main(String[] args) throws IOException {
          //创建客户端的Socket对象(Socket)
          //Socket(String host, int port) 创建流套接字并将其连接到指定主机上的指定端口号
          Socket s = new Socket("127.0.0.1",10000);
          //获取输出流,写数据
          //OutputStream getOutputStream() 返回此套接字的输出流
          OutputStream os = s.getOutputStream();
          os.write("hello,tcp,我来了".getBytes());
          //释放资源
          s.close();
      }
  }

14-TCP-服务器

  • 构造方法

  • 相关方法

  • 注意事项

      1. accept方法是阻塞的,作用就是等待客户端连接
      1. 客户端创建对象并连接服务器,此时是通过三次握手协议,保证跟服务器之间的连接
      1. 针对客户端来讲,是往外写的,所以是输出流 针对服务器来讲,是往里读的,所以是输入流
      1. read方法也是阻塞的
      1. 客户端在关流的时候,还多了一个往服务器写结束标记的动作
      1. 最后一步断开连接,通过四次挥手协议保证连接终止

15-TCP-原理分析

16-TCP-三次握手

17-TCP-四次挥手

  public class ServerDemo {
      public static void main(String[] args) throws IOException {
          //创建服务器端的Socket对象(ServerSocket)
          //ServerSocket(int port) 创建绑定到指定端口的服务器套接字
          ServerSocket ss = new ServerSocket(10000);
          //Socket accept() 侦听要连接到此套接字并接受它
          Socket s = ss.accept();
          //获取输入流,读数据,并把数据显示在控制台
          InputStream is = s.getInputStream();
          byte[] bys = new byte[1024];
          int len = is.read(bys);
          String data = new String(bys,0,len);
          System.out.println("数据是:" + data);
          //释放资源
          s.close();
          ss.close();
      }
  }

10-6 HTTP服务器

21-HTTP协议-简介

超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII形式给出;而消息内容则具有一个类似MIME的格式。

22-URL

统一资源定位器(Uniform Resource Locators) URL 是一个网页地址。

scheme://host.domain:port/path/filename
  • scheme - 定义因特网服务的类型。最常见的类型是 http
  • host - 定义域主机(http 的默认主机是 www)
  • domain - 定义因特网域名
  • :port - 定义主机上的端口号(http 的默认端口号是 80)
  • path - 定义服务器上的路径(如果省略,则文档必须位于网站的根目录中)。
  • filename - 定义文档/资源的名称

23-抓包工具

F12

26-HTTP协议

客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成,下图给出了请求报文的一般格式。

29-HTTP协议

HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。

HTTP协议-请求方法

HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD 方法。

HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。

HTTP Content-type 对照表

HTTP 状态码

11 基础加强

11-1 类加载器

01-类加载器-了解

负责将.class文件(存储的物理文件)加载在到内存中

02-类加载器-类加载时机

  • 类加载时机 创建类的实例(对象)

    • 调用类的类方法
    • 访问类或者接口的类变量,或者为该类变量赋值
    • 使用反射方式来强制创建某个类或接口对应的java.lang.Class对初始化某个类的子类
    • 直接使用java.exe命令来运行某个主类

03-类加载的过程-加载+链接

  • 类加载过程
    • 1 . 加载
      • 通过包名 + 类名,获取这个类,准备用流进行传输
      • 在这个类加载到内存中
      • 加载完毕创建一个class对象

  • 2 . 链接
    • 验证

确保Class文件字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身 安全(文件中的信息是否符合虚拟机规范有没有安全隐患)

  • 准备
    • 负责为类的类变量(被static修饰的变量)分配内存,并设置默认初始化值 (初始化静态变量)

  • 解析
    • 将类的二进制数据流中的符号引用替换为直接引用 (本类中如果用到了其他类,此时就需要找到对应的类)

  • 3 .初始化
    • 根据程序员通过程序制定的主观计划去初始化类变量和其他资源 (静态变量赋值以及初始化其他资源)

05-类加载的过程-初始化和小结

  • 小结
    • 当一个类被使用的时候,才会加载到内存
    • 类加载的过程: 加载、验证、准备、解析、初始化

06-类加载器-分类

  • 分类

    • Bootstrap class loader:虚拟机的内置类加载器,通常表示为null ,并且没有父null
    • Platform class loader:平台类加载器,负责加载JDK中一些特殊的模块
    • System class loader:系统类加载器,负责加载用户类路径上所指定的类库
  • 类加载器的继承关系

    • System的父加载器为Platform
    • Platform的父加载器为Bootstrap
  public class ClassLoaderDemo1 {
      public static void main(String[] args) {
          //获取系统类加载器
          ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
          //获取系统类加载器的父加载器 --- 平台类加载器
          ClassLoader classLoader1 = systemClassLoader.getParent();
          //获取平台类加载器的父加载器 --- 启动类加载器
          ClassLoader classLoader2 = classLoader1.getParent();
          System.out.println("系统类加载器" + systemClassLoader);
          System.out.println("平台类加载器" + classLoader1);
          System.out.println("启动类加载器" + classLoader2);
      }
  }

07-类加载器-双亲委派模型

介绍

如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载 器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达 顶层的启动类加载器,如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完 成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式

08-类加载器-常用方法

  public class ClassLoaderDemo2 {
      public static void main(String[] args) throws IOException {
          //static ClassLoader getSystemClassLoader() 获取系统类加载器
          //InputStream getResourceAsStream(String name)  加载某一个资源文件
          //获取系统类加载器
          ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
          //利用加载器去加载一个指定的文件
          //参数:文件的路径(放在src的根目录下,默认去那里加载)
          //返回值:字节流。
          InputStream is = systemClassLoader.getResourceAsStream("prop.properties");
          Properties prop = new Properties();
          prop.load(is);
          System.out.println(prop);
          is.close();

      }

  }

11-2 反射

09-反射-概述

反射机制

是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法; 对于任意一个对象, 都能够调用它的任意属性和方法; 这种动态获取信息以及动态调用对象方法的功能称为Java语言 的反射机制。

10-反射-获取class对象

  • 三种方式分类
    • 类名.class属性
    • 对象名.getClass()方法
    • Class.forName(全类名)方法

11-反射-获取Constructor对象

12-反射-利用Constructor创建对象

13-反射-小结

  • 获取class对象
    • 三种方式: Class.forName(“全类名”), 类名.class, 对象名.getClass()
  • 获取里面的构造方法对象
    • getConstructor (Class... parameterTypes) getDeclaredConstructor (Class... parameterTypes)
  • 如果是public的,直接创建对象
    • newInstance(Object... initargs)
  • 如果是非public的,需要临时取消检查,然后再创建对象
    • setAccessible(boolean) 暴力反射

14-反射-获取Field对象

15-反射-利用Field赋值和获取值

16-反射-获取Method对象

17-反射-利用Method对象运行方法

参数一: 用obj对象调用该方法

参数二: 调用方法的传递的参数(如果没有就不写)

返回值: 方法的返回值(如果没有就不写)