网络编程
概述
网络编程中有两个主要的问题:
- 如何准确地定位网络上一台或多台主机;定位主机上的特定的应用
- 找到主机后如何可靠高效地进行数据传输
网络编程中的两个要素:
- 对应问题一:IP和端口号
- 对应问题二:提供网络通信协议:TCP/IP参考模型(应用层、传输层、网络层、物理+数据链路层)
通信要素一:
IP和端口号
- IP:唯一的标识 Internet 上的计算机(通信实体)
- 在Java中使用InetAddress类代表IP
- IP分类:IPv4 和 IPv6 ; 万维网 和 局域网
- 域名: www.baidu.com www.mi.com www.sina.com www.jd.com
- 本地回路地址:127.0.0.1 对应着:localhost
- 如何实例化InetAddress:两个方法:getByName(String host) 、 getLocalHost()
- 两个常用方法:getHostName() / getHostAddress()
- 端口号:正在计算机上运行的进程。
- 要求:不同的进程有不同的端口号
- 范围:被规定为一个 16 位的整数 0~65535。
- 端口号与IP地址的组合得出一个网络套接字:Socket
1 | public static void main(String[] args) { |
实现TCP的网络编程
- 例题3:从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端。
- 并关闭相应的连接。
1 |
|
UDPd协议的网络编程
1 | //发送端 |
URL网络编程
URL:统一资源定位符,对应着互联网的某一资源地址
格式:
http://localhost:8080/examples/beauty.jpg?username=Tom
协议 主机名 端口号 资源地址 参数列表
1 | public static void main(String[] args) { |
1 | public static void main(String[] args) { |
*idea快捷键:
- 重构一切:Ctrl+Shift+Alt+T
- 智能补全:Ctrl+Shift+Space
- 选你所想:Ctrl+W
- 自我修复:Alt+Enter
- 自动完成:Ctrl+Shift+Enter
- 可以新建类、方法等任何东西、get/set、toString方法: alt+insert
- 自动new完整对象: Ctrl+Alt+V,可以引入变量
- 自动选中模块代码:Ctrl+W
- 移动到前/后方法:Alt+Forward/Backward
- 删除行:Ctrl+Y、复制:Ctrl+D
- 切换vim模式:Ctrl+;
- 高亮错误或警告快速定位:F2或shift+F2
- 打开类或资源:Ctrl+N/Ctrl+Shift+N
- 弹出框中搜索任何东西,包括类、资源、配置项、方法:Shift+Shift
- 查看当前类的所有方法:Ctrl+F12
- 找到类或方法使用的地方:,Alt+F7
- 格式化import列表:Ctrl+Alt+O,格式化代码:Ctrl+Alt+L
- 查看项目结构选中类:Alt+1,查看搜索窗口:Alt+3,查看运行调试Alt+4/5
- 打开最近打开或编辑过的文件列表:Ctrl+E
- 运行程序:Alt+Shift+F10,启动调试:Shift+F9,停止:Ctrl+F2。
- 调试:F7/F8/F9分别对应Step into,Step over,Continue
- 上/下移一行:Alt+Shift+Up/Down
反射
概述
反射的特征:动态性
疑问1:通过直接new的方式或反射的方式都可以调用公共的结构,开发中到底用那个?
建议:直接new的方式。
什么时候会使用:反射的方式。
疑问2:反射机制与面向对象中的封装性是不是矛盾的?如何看待两个技术?
不矛盾。
java.lang.Class类的理解
- 类的加载过程:
程序经过javac.exe命令以后,会生成一个或多个字节码文件(.class结尾)。 接着我们使用java.exe命令对某个字节码文件进行解释运行。相当于将某个字节码文件 加载到内存中。此过程就称为类的加载。加载到内存中的类,我们就称为运行时类,此 运行时类,就作为Class的一个实例。
- 换句话说,Class的实例就对应着一个运行时类。
- 加载到内存中的运行时类,会缓存一定的时间。在此时间之内,我们可以通过不同的方式来获取此运行时类。
获取Class的实例的方式
- 调用运行时类的属性:.class
- 通过运行时类的对象,调用getClass()
- 调用Class的静态方法:forName(String classPath)
- 使用类的加载器:ClassLoader (了解)
1 | //(前三种方式需要掌握) |
Class实例可以是哪些结构的说明:
1 | //万事万物皆对象?对象.xxx,File,URL,反射,前端、数据库操作 |
了解类的加载器
1 |
|
使用 ClassLoader加载配置文件
1 | //Properties:用来读取配置文件。 |
通过反射
创建运行时类的对象
- newInstance(): 调用此方法,创建对应的运行时类的对象。内部调用了运行时类的空参的构造器。
要想此方法正常的创建运行时类的对象,要求:
- 运行时类必须提供空参的构造器
- 空参的构造器的访问权限得够。通常,设置为public。
在javabean中要求提供一个public的空参构造器。原因:
1.便于通过反射,创建运行时类的对象
2.便于子类继承此运行时类时,默认调用super()时,保证父类有此构造器
1 |
|
体会反射的动态性
1 |
|
获取运行时类的完整结构
属性结构
- getFields(): 获取当前运行时类及其父类中声明为public访问权限的属性
- getDeclaredFields(): 获取当前运行时类中声明的所有属性。(不包含父类中声明的属性)
1 |
|
权限修饰符 数据类型 变量名
1 |
|
方法结构
- getMethods(): 获取当前运行时类及其所有父类中声明为public权限的方法
- getDeclaredMethods(): 获取当前运行时类中声明的所有方法。(不包含父类中声明的方法)
1 |
|
权限修饰符 返回值类型 方法名(参数类型1 形参名1,…) throws XxxException{}
1 |
|
构造器结构
- getConstructors(): 获取当前运行时类中声明为public的构造器
- getDeclaredConstructors(): 获取当前运行时类中声明的所有的构造器
1 |
|
其他结构
获取运行时类的父类
1 |
|
获取运行时类的带泛型的父类
1 |
|
获取运行时类的带泛型的父类的泛型
1 |
|
获取运行时类实现的接口
1 |
|
获取运行时类所在的包
1 |
|
获取运行时类声明的注解
1 |
|
调用运行时类的指定结构
属性、方法、构造器
1 | // 不需要掌握 |
操作指定的属性
1 | /* |
指定的方法
1 | /* |
指定的构造器
1 | /* |
应用:动态代理
静态代理举例
特点:代理类和被代理类在编译期间,就确定下来了。
1 | interface ClothFactory{ |
动态代理的举例
要想实现动态代理,需要解决的问题?
问题一:如何根据加载到内存中的被代理类,动态的创建一个代理类及其对象。
问题二:当通过代理类的对象调用方法a时,如何动态的去调用被代理类中的同名方法a。
1 | interface Human{ |