178_刘鉴_java笔记12

Java笔记12

  • Java 网络编程

网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。

​java.net 包中 J2SE 的 API 包含有类和接口,它们提供低层次的通信细节。你可以直接使用这些类和接口,来专注于解决问题,而不用关注通信细节。

java.net 包中提供了两种常见的网络协议的支持:

TCP:TCP(英语:Transmission Control Protocol,传输控制协议) 是一种面向连接的、可靠的、基于字节流的传输层通信协议,TCP 层是位于 IP 层之上,应用层之下的中间层。TCP 保障了两个应用程序之间的可靠通信。通常用于互联网协议,被称 TCP / IP。

UDP:UDP (英语:User Datagram Protocol,用户数据报协议),位于 OSI 模型的传输层。一个无连接的协议。提供了应用程序之间要发送数据的数据报。由于UDP缺乏可靠性且属于无连接协议,所以应用程序通常必须容许一些丢失、错误或重复的数据包。

1、Socket 编程

以下步骤在两台计算机之间使用套接字建立TCP连接时会出现:

​1、服务器实例化一个 ServerSocket 对象,表示通过服务器上的端口通信。

​2、服务器调用 ServerSocket 类的 accept() 方法,该方法将一直等待,直到客户端连接到服务器上给定的端口。

​3、服务器正在等待时,一个客户端实例化一个 Socket 对象,指定服务器名称和端口号来请求连接。

​4、Socket 类的构造函数试图将客户端连接到指定的服务器和端口号。如果通信被建立,则在客户端创建一个 Socket 对象能够与服务器进行通信。

​5、在服务器端,accept() 方法返回服务器上一个新的 socket 引用,该 socket 连接到客户端的 socket。以下步骤在两台计算机之间使用套接字建立TCP连接时会出现:

​1、服务器实例化一个 ServerSocket 对象,表示通过服务器上的端口通信。

​2、服务器调用 ServerSocket 类的 accept() 方法,该方法将一直等待,直到客户端连接到服务器上给定的端口。

​3、服务器正在等待时,一个客户端实例化一个 Socket 对象,指定服务器名称和端口号来请求连接。

​4、Socket 类的构造函数试图将客户端连接到指定的服务器和端口号。如果通信被建立,则在客户端创建一个 Socket 对象能够与服务器进行通信。

​5、在服务器端,accept() 方法返回服务器上一个新的 socket 引用,该 socket 连接到客户端的 socket。

连接建立后,通过使用 I/O 流在进行通信,每一个socket都有一个输出流和一个输入流,客户端的输出流连接到服务器端的输入流,而客户端的输入流连接到服务器端的输出流。

 2、Socket整体流程

​Socket编程主要涉及到客户端和服务端两个方面,首先是在服务器端创建一个服务器套接字(ServerSocket),并把它附加到一个端口上,服务器从这个端口监听连接。端口号的范围是0到65536,但是0到1024是为特权服务保留的端口号,我们可以选择任意一个当前没有被其他进程使用的端口。

​客户端请求与服务器进行连接的时候,根据服务器的域名或者IP地址,加上端口号,打开一个套接字。当服务器接受连接后,服务器和客户端之间的通信就像输入输出流一样进行操作。

  1. ServerSocket 类的方法

创建非绑定服务器套接字。 如果 ServerSocket 构造方法没有抛出异常,就意味着你的应用程序已经成功绑定到指定的端口,并且侦听客户端请求。

创建非绑定服务器套接字。 如果 ServerSocket 构造方法没有抛出异常,就意味着你的应用程序已经成功绑定到指定的端口,并且侦听客户端请求。

创建非绑定服务器套接字。 如果 ServerSocket 构造方法没有抛出异常,就意味着你的应用程序已经成功绑定到指定的端口,并且侦听客户端请求。

 反射

 一、反射概念

​Java 反射机制是 Java 语言的一个重要特性。在学习 Java 反射机制前,先了解两个概念,编译期和运行期。

​编译期是指把源码交给编译器编译成计算机可以执行的文件的过程。在 Java 中也就是把 Java 代码编成 class 文件的过程。编译期只是做了一些翻译功能,并没有把代码放在内存中运行起来,而只是把代码当成文本进行操作,比如检查错误。

​运行期是把编译后的文件交给计算机执行,直到程序运行结束。所谓运行期就把在磁盘中的代码放到内存中执行起来。

Java 反射机制主要提供了以下功能,这些功能都位于java.lang.reflect包。

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

​2、在运行时构造任意一个类的对象。

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

​4、在运行时调用任意一个对象的方法。

​5、生成动态代理。

利用 Class 类的对象 demo 可以访问 Demo01 对象的描述信息、Demo01 类的信息以及基类 Object 的信息。下表列出了通过反射可以访问的信息。

 

Java 反射机制的优缺点

优点:

能够运行时动态获取类的实例,大大提高系统的灵活性和扩展性。

与 Java 动态编译相结合,可以实现无比强大的功能。

对于 Java 这种先编译再运行的语言,能够让我们很方便的创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代码的链接,更加容易实现面向对象。

缺点:

​反射会消耗一定的系统资源,因此,如果不需要动态地创建一个对象,那么就不需要用反射;

​反射调用方法时可以忽略权限检查,获取这个类的私有方法和属性,因此可能会破坏类的封装性而导致安全问题。

 二、反射机制API

​实现 Java 反射机制的类都位于 java.lang.reflect 包中,java.lang.Class 类是 Java 反射机制 API 中的核心类。

每一种类型包括类和接口等,都有一个 class 静态变量可以获得 Class 实例。另外,每一个对象都有 getClass() 方法可以获得 Class 实例,该方法是由 Object 类提供的实例方法。

2、java.lang.reflect 包

java.lang.reflect 包提供了反射中用到类,主要的类说明如下:

  • Constructor 类:提供类的构造方法信息。
  • Field 类:提供类或接口中成员变量信息。
  • Method 类:提供类或接口成员方法信息。
  • Array 类:提供了动态创建和访问 Java 数组的方法。
  • Modifier 类:提供类和成员访问修饰符信息。

 三、通过反射访问构造方法

​为了能够动态获取对象构造方法的信息,首先需要通过下列方法之一创建一个 Constructor 类型的对象或者数组。

​getConstructors()

​getConstructor(Class<?>…parameterTypes)

​getDeclaredConstructors()

​getDeclaredConstructor(Class<?>...parameterTypes)

​如果是访问指定的构造方法,需要根据该构造方法的入口参数的类型来访问。

创建的每个 Constructor 对象表示一个构造方法,然后利用 Constructor 对象的方法操作构造方法。Constructor 类的常用方法如表 1 所示。

通过 java.lang.reflect.Modifier 类可以解析出 getMocMers() 方法的返回值所表示的修饰符信息。在该类中提供了一系列用来解析的静态方法,既可以查看是否被指定的修饰符修饰,还可以字符串的形式获得所有修饰符。表 2 列出了 Modifier 类的常用静态方法。

 四、通过反射执行方法

​要动态获取一个对象方法的信息,首先需要通过下列方法之一创建一个 Method 类型的对象或者数组。

​getMethods()

​getMethods(String name,Class<?> …parameterTypes)

​getDeclaredMethods()

​getDeclaredMethods(String name,Class<?>...parameterTypes)

​如果是访问指定的构造方法,需要根据该方法的入口参数的类型来访问。例如,访问一个名称为 max,入口参数类型依次为 int 和 String 类型的方法。

Method 类的常用方法如下表 所示。

 

 五、通过反射访问成员变量

​通过下列任意一个方法访问成员变量时将返回 Field 类型的对象或数组。

​getFields()

​getField(String name)

​getDeclaredFields()

​getDeclaredField(String name)

Field 类的常用方法如下表 所示

 

 

 

六、获取继承关系

当我们获取到某个Class对象时,实际上就获取到了一个类的类型:

Class cls = String.class; // 获取到String的Class

还可以用实例的getClass()方法获取:

String s = "";

Class cls = s.getClass(); // s是String,因此获取到String的Class

最后一种获取Class的方法是通过Class.forName(""),传入Class的完整类名获取:

Class s = Class.forName("java.lang.String");

这三种方式获取的Class实例都是同一个实例,因为JVM对每个加载的Class只创建一个Class实例来表示它的类型。

1、获取父类的Class

2、获取interface

3、继承关系

通过Class对象可以获取继承关系:

  • Class getSuperclass():获取父类类型;
  • Class[] getInterfaces():获取当前类实现的所有接口。

通过Class对象的isAssignableFrom()方法可以判断一个向上转型是否可以实现。

 七、动态代理

我们来比较Java的`class`和`interface`的区别:

可以实例化`class`(非`abstract`);

不能实例化`interface`。

在运行期动态创建一个`interface`实例的方法如下:

​1、定义一个InvocationHandler实例,它负责实现接口的方法调用;

​2、通过Proxy.newProxyInstance()创建interface实例,它需要3个参数:

​2.1、使用的ClassLoader,通常就是接口类的ClassLoader;

​2.2、需要实现的接口数组,至少需要传入一个接口进去;

​2.3、用来处理接口方法调用的InvocationHandler实例。

​3、将返回的Object强制转型为接口。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值