Java基础知识(13)
(包括网络编程,反射,.动态代理)
目录
[1. 网络编程基础](#1. 网络编程基础)
(3)Java中可以使用java.net包下的技术轻松开发出常见的网络应用程序。
[2. 网络编程三要素](#2. 网络编程三要素)
1) IPV4 IPV4)
2) IPv6 IPv6)
3)小结小结)
1)发送数据发送数据)
2)接收数据接收数据)
[(6) UDP的三种通信方式(代码实现)](#(6) UDP的三种通信方式(代码实现))
①创建客户端的Socket对象(Socket)与指定服务端连接
①创建服务器端的Socket对象(Serversocket)
5)TCP通信程序(四次挥手)(确保连接断开,且数据处理完毕)
[二. 反射](#二. 反射)
(1)反射:反射允许对成员变量,成员方法和构造方法的信息进行编程访问
[2. 获取class对象的三种方式](#2. 获取class对象的三种方式)
[3. 利用反射获取构造方法](#3. 利用反射获取构造方法)
[4. 利用反射获取成员变量](#4. 利用反射获取成员变量)
[5. 利用反射获取成员方法](#5. 利用反射获取成员方法)
[6. 反射的作用](#6. 反射的作用)
[2. 如何为Java对象创建一个代理对象](#2. 如何为Java对象创建一个代理对象)
一.网络编程
1. 网络编程基础
(1)什么是网络编程
在网络通信协议下,不同计算机上运行的程序,进行的数据传输
(2)应用场景:
即时通信、网游对战、金融证券、国际贸易、邮件、等等
不管是什么场景,都是计算机跟计算机之间通过网络进行数据传输。
(3)Java中可以使用java.net包下的技术轻松开发出常见的网络应用程序。
(4)常见的软件架构
1)C/S: Client/Server客户端/服务器(需要安装)
2)B/S: Browser/Server浏览器/服务器(不需要安装)
(5)BS架构的优缺点
1)不需要开发客户端,只需要页面+服务端
2)用户不需要下载,打开浏览器就能使用
3)但如果应用过大,用户体验受到影响
(6)CS架构的优缺点
1)画面可以做的非常精美,用户体验好
2)需要开发客户端,也需要开发服务端
3)用户需要下载和更新的时候太麻烦
2. 网络编程三要素
(1)简介
IP:设备在网络中的地址,是唯一的标识,
端口号:应用程序在设备中唯一的标识
协议:数据在网络中传输的规则,常见的协议有UDP、TCP、http、https、ftp。
(2)IP
全称:Internet Protocol,是互联网协议地址,也称IP地址,是分配给上网设备的数字标签。
通俗理解:上网设备在网络中的地址,是唯一的
常见的IP分类为:IPv4、IPv6
1) IPV4
全称:Internet Protocolversion4,互联网通信协议第四版。
采用32位地址长度,分成4组
2) IPv6
全称:InternetProtocolversion6,互联网通信协议第六版。
由于互联网的蓬勃发展,IP地址的需求量愈来愈大,而IPv4的模式下IP的总数是有限的。
采用128位地址长度,分成8组。
3)小结
①IP的作用
设备在网络中的地址,是唯一的标识
②IPv4有什么特点
目前的主流方案
最多只有2^32次方个ip,目前已经用完了
③IPv6有什么特点
为了解决IPv4不够用而出现的
最多有2^128次方个ip
可以为地球上的每一粒沙子都设定ip
4)IPv4的地址分类形式
①公网地址(万维网使用)和私有地址(局域网使用)。
②192.168.开头的就是私有址址,范围即为192.168.0.0--192.168.255.255,专门为组织机构内部使用,以此节省IP
③特殊IP地址
127.0.0.1,也可以是localhost:是回送地址也称本地回环地址,也称本机IP,永远只会寻找当前所在本机。
5)InetAddress
static InetAddress getByName(string host):确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址
String getHostName() 获取此IP地址的主机名
String getHostAddress() 返回文本显示中的IP地址字符串
//IP的对象 一台电脑的对象
InetAddress address = InetAddress.getByName("z");
System.out.println(address); //192.168.1.108
String name = address.getHostName();
System.out.println(name)://z
String ip = address.getHostAddress();
System.out.println(ip)://192.168.1.108
(3)端口号
1)应用程序在设备中唯一的标识。
2)端口号:由两个字节表示的整数,取值范围:0~65535,其中0~1023之间的端口号用于一些知名的网络服务或者应用。我们自己使用1024以上的端口号就可以了。
3)注意:一个端口号只能被一个应用程序使用,
(4)协议
1)计算机网络中,连接和通信的规则被称为网络通信协议
①OSI参考模型:世界互联协议标准,全球通信规范,单模型过于理想化,未能在因特网上进行广泛推厂
②TCP/IP参考模型(或TCP/IP协议):事实上的国际标准。
2)TCP/IP参考模型
应用层 HTTP、FTP、Telnet、 DNs...
传输层 TCP、 UDP.
网络层 TCP、 UDP.
物理链路层 硬件设备010101010101
3)UDP协议
①用户数据报协议(User Datagram Protocol)
②UDP是面向无连接通信协议。速度快,有大小限制一次最多发送64K,数据不安全,易丢失数据
4)TCP协议
①传输控制协议TCP(Transmission Control Protocol)
②TCP协议是面向连接的通信协议。速度慢,没有大小限制,数据安全
(5)UDP通信程序
1)发送数据
①步骤
创建发送端的DatagramSocket对象
数据打包(DatagramPacket)
发送数据
释放资源
②案例
//1.创建Datagramsocket对象(快递公司)
/细节:
//绑定端口,以后我们就是通过这个端口往外发送
//空参:所有可用的端口中随机一个进行使用
//有参:指定端口号进行绑定
DatagramSocket ds=new DatagramSocket();
String str="你好!!!"
bytell bytes = str.getBytes();
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 10086;
DatagramPacket dp = new DatagramPacket (bytes, bytes.length, address, port),
ds.send(dp);
ds.close();
2)接收数据
①步骤
创建接收端的Datagramsocket对象
接收打包好的数据
解析数据包
释放资源
②案例
//1.创建Datagramsocket对象(快递公司)
//细节:
//在接收的时候,一定要绑定端口
//而且绑定的端口一定要跟发送的口保持一致
DatagramSocket ds=new DatagramSocket( port: 10086);
bytel] bytes = new byte[1024];
DatagramPacket dp= new DatagramPacket(bytes,bytes.length),
//该方法是阻寒的(receive)
//程序执行到这一步的时候,会在这里死等
//等发送端发送消息
ds .receive(dp);
bytel] data = dp.getData();
int len = dp.getLength();
InetAddress address = dp.getAddress();
int port = dp.getPort();
System.out.println("按收数据"+ new string(data,offset: 0,len));
System.out.print1n("该数据是从"+ address +"这台电脑中的"+ port +"这个端口发出的");
ds.close();
(6) UDP的三种通信方式(代码实现)
1)单播:以前的代码就是单播(1对1发送)
2)组播
组播地址:224.0.0.0~239.255.255.255
其中224.0.0.0~224.0.0.255为预留的组播地址
接收代码跟以前几乎一样,只是要指定组播地址
InetAddress address = InetAddress.getByName("224.0.0.1");
接收代码多了一步
//2.将将当前本机,添加到224.0.0.1的这一组当中
InetAddress address = InetAddress.getByName("224.0.0.1");
ms.joinGroup(address);
3)广播
广播地址:255.255.255.255
接收代码跟以前几乎一样,只是要指定组播地址
InetAddress address = InetAddress.getByName("255.255.255.255");
发送代码跟以前一样
(7)TCP通信程序
1)TCP通信协议简介
TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象
通信之前要保证连接已经建立
通过Socket产生I0流来进行网络通信
2)客户端
①创建客户端的Socket对象(Socket)与指定服务端连接
Socket(string host, int port)
②获取输出流,写数据
Outputstream getoutputstream()
③释放资源
void close()
④案例
//TCP协议,发送数据
//细节:在创建对象的同时会连接服务端,如果连接不上,代码会报错
Socket socket = new Socket( host:"127.0.0.1",port: 10000);
Outputstream os=socket.getoutputstream();
//写出数据
os.write("你好你好".getBytes());(不能传中文)
os.close();
socket.close();
3)服务器
①创建服务器端的Socket对象(Serversocket)
Serversocket(int port)
②监听客户端连接,返回一个Socket对象
Socket accept()
③获取输入流,读数据,并把数据显示在控制台
Inputstream getInputstream()
④释放资源
void close()
⑤案例
//TCP协议,接收数据
ServerSocketss =new serverSocket( port:10080);
Socket socket= ss.accept();
Inputstream is = socket.getInputStream();
InputstreamReader isr =new InputstreamReader(is);
int b;
while((b=isr.read())!=-1){
System.out.print((char)b);
socket.close();
ss.close();
4)TCP通信程序(三次握手)(确保连接建立)
①客户端向服务器发出连接请求,等待服务器确认
②服务器向客户端返回一个响应,告诉客户端收到了请求
③客户端向服务器再次发出确认信息,连接建立
5)TCP通信程序(四次挥手)(确保连接断开,且数据处理完毕)
①客户端向服务器发出取消连接请求
②服务器向客户端返回一个响应,表示收到客户端取消请求(服务器将最后的数据,处理完毕)
③服务器向客户端发出确认取消信息
④客户端再次发送确认消息,连接取消
二. 反射
1.基础知识
(1)反射:反射允许对成员变量,成员方法和构造方法的信息进行编程访问
(2)多种类
获取class对象 Class
构造方法 Constructor
字段(成员变量) Field
成员方法 Method
2. 获取class对象的三种方式
(1)分类
Class.forName("全类名");
类名.class
对象.getclass();
(2)案例
//全类名: 包名 +名
//最为常用的
Class clazz1 =class,forName("com,itheima.myreflect1.student");
//一般更多的是当做参数进行传递
Class clazz2 = Student,class;
//当我们已经有了这个类的对象时,才可以使用。
student s= new student();
Class clazz3=s.getclass();
3. 利用反射获取构造方法
(1)Class类中用于获取构造方法的方法
①Constructor<?>[]getConstructors():返回所有公共构造方法对象的数组
②Constructor<?>[]getDeclaredConstructors():返回所有构造方法对象的数组(包括私有)
③Constructor<T>getConstructor(Class<?>... parameterTypes):返回单个公共构造方法对象
④Constructor<T>getDeclaredConstructor(Class<?>.. parameterTypes):返回单个构造方法对象(包括私有)
⑤案例
Class clazz= Class.forName("com.itheima.myreflect2.student");
Constructor[]cons1=clazz.getconstructors();
for(constructor con:cons1){
System.out.println(con);
Constructor con2=clazz.getDeclaredconstructor(string.class);
(2)Constructor类中用于创建对象的方法
①T newInstance(Object...initargs):根据指定的构造方法创建对象
②setAccessible(boolean flag):设置为true,表示取消访问检查
③案例
//暴力反射:表示临时取消权限校验(可以使用私有构造)
con4.setAccessible(true);
Student stu=(student)con4.newInstance("张",23);
System.out.printin(stu);
4. 利用反射获取成员变量
(1)Class类中用于获取成员变量的方法
①Field[]getFields():返回所有公共成员变量对象的数组
②Field[}getDeclaredFields():返回所有成员变量对象的数组
③Field getField(String name): 返回单个公共成员变量对象
④Field getDeclaredField(String name):返回单个成员变量对象
⑤案例
//获取单个的成员变量
Field name= clazz.getDeclaredField( name:"name");
System.out.println(name);
//获取权限修饰符
int modifiers = name.getModifiers(),
System.out.println(modifiers);
//获取成员变量的名字
String n= name.getName();
System.out.println(n);
//获取成员变量的数据类型
Class<?> type = name.getType();
System.out.printin(type);
//获取成员变量记录的值
Student s= new student( name:"zhangsan",age: 23, gender:""");
name.setAccessible(true);
String value =(string) name.get(s);
System.out.println(value);
//修改对象里面记录的值
name.set(s,"lisi");
(2)Field类中用于创建对象的方法
①void set(Object obj, Object value):赋值
②Object get(Object obj)获取值。
5. 利用反射获取成员方法
(1)Class类中用于获取成员方法的方法
①Method[lgetMethods():返回所有公共成员方法对象的数组,包括继承的
②Method[]getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
③Method getMethod(String name, Class<?>.. parameterTypes):返回单个公共成员方法对象
④Method getDeclaredMethod(String name, Class<?>.. parameterTypes):返回单个成员方法对象
⑤案例
(2)Method类中用于创建对象的方法
①Object invoke(Object obj, Object..args):运行方法
参数一:用obi对象调用该方法
参数二:调用方法的传递的参数(如果没有就不写)
返回值:方法的返回值(如果没有就不写)
②一系列get...方法。
③案例
student s= new student();
m.setAccessible(true);
//参数一s:表示方法的调用者
//参数二"汉堡包":表示在调用方法的时候传递的实际参数
Object result =m.invoke(s,"汉堡包");
System.out.printin(result);
6. 反射的作用
①获取一个类里面所有的信息,获取到了之后,再执行其他的业务逻辑
②结合配置文件,动态的创建对象并调用方法
三.动态代理
1.基础知识
(1)为什么需要代理?
代理可以无侵入式的给对象增强其他的功能
调用者 -> 代理 -> 对象
(2)代理长什么样?
代理里面就是对象要被代理的方法
(3)Java通过什么来保证代理的样子?
通过接口保证,后面的对象和代理需要实现同一个接口
接口中就是被代理的所有方法
2. 如何为Java对象创建一个代理对象
(1)方法
java.lang.reflect.Proxy类:提供了为对象产生代理对象的方法:
public static object newProxyInstance(classLoader loader, Class<?>[] interfaces, InvocationHandler h)
参数一:用于指定用哪个类加载器,去加载生成的代理类
参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法
参数三:用来指定生成的代理对象要于什么事情
(2)案例
1)主体
需求:
外面的人想要大明星唱一首歌
①获取代理的对象:代理对象 = ProxyUtil.createProxy(大明星的对象);
②再调用代理的唱歌方法:代理对象.唱歌的方法("只因你太美")
Bigstar bigstar = new Bigstar( name:"鸡拼");
star proxy= ProxyUtil.createProxy(bigstar);
String result = proxy.sing( "只内你太美");
System.out.println(result);
2)创建代理
public static star createProxy(Bigstar bigstar){
Star star=(star)Proxy.newProxyInstance(
Proxyuti1.class.getclassLoader(),//参数一:用于指定用哪个类加载器,去加载生成的代理类
new class[]{star.class},//参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法
//参数三:用来指定生成的代理对象要干什么事情
new InvocationHandler(){
@override
public object invoke(object proxy, Method method, object[] args) throws Throwable {
*参数一:代理的对象
*参数二:要运行的方法 sing
*参数三:调用sing方法时,传递的实参
if("sing".equals(method.getName())){
System.out.println("准备话简,收钱");
}else if("dance".equals(method.getName())){
System.out.println("准备场地,收钱");
//去找大明星开始唱歌或者跳舞
//代码的表现形式:调用大明星里面唱歌或者跳舞的方法
return method.invoke(bigstar,args);
}
}
};
Return star;
}