欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

学习大数据的第28天——UDP、TCP传输以及类加载器、反射和动态代理

时间:2023-04-20
UDP传输

1:建立udp的socket服务.
2:通过receive方法接收数据
3:将收到的数据存储到数据包对象中
4:通过数据包对象的功能来完成对接收到数据进行解析.
5:可以对资源进行关闭

客户端

public class UploadClient { public static void main(String[] args) throws Exception { //1、创建Socket对象 Socket s = new Socket("192.168.7.64", 12345); //2、获取本地的字符输入流对象 BufferedReader br = new BufferedReader(new FileReader("src\com\shujia\yl\day25\DieLockDemo.java")); //3、获取通道中的字节输出流对象 OutputStream outputStream = s.getOutputStream(); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); BufferedWriter bw = new BufferedWriter(outputStreamWriter); String line = null; while ((line = br.readLine()) != null) { bw.write(line); bw.newline(); bw.flush(); } //自定义一个结束标记// bw.write("over");// bw.newline();// bw.flush(); //通知服务器我没有数据过来了,你也别等了 s.shutdownOutput(); //获取通道中字节输入流对象 InputStream inputStream = s.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream); BufferedReader br2 = new BufferedReader(inputStreamReader); String s1 = br2.readLine(); // 阻塞 等待服务给出反馈 System.out.println(s1); //释放资源 br.close(); s.close(); }}

服务端

public class UploadServer { public static void main(String[] args) throws Exception { //1、创建服务器端的ServerSocket对象 ServerSocket ss = new ServerSocket(12345); //2、监听客户端与之的连接,获取对应的Socket对象 Socket s = ss.accept(); //3、获取通道中的字节输入流对象 InputStream inputStream = s.getInputStream(); InputStreamReader isr = new InputStreamReader(inputStream); BufferedReader br = new BufferedReader(isr); //4、创建普通的字符输出流对象 BufferedWriter bw = new BufferedWriter(new FileWriter("netFile.txt")); String line = null; while ((line=br.readLine())!=null){// if("over".equals(line)){// break;// } bw.write(line); bw.newline(); bw.flush(); } //服务器给出反馈 //获取通道中字节输出流对象 OutputStream outputStream = s.getOutputStream(); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); BufferedWriter bw2 = new BufferedWriter(outputStreamWriter); bw2.write("文件上传成功"); bw2.newline(); bw2.flush(); //释放资源 bw.close(); s.close(); }}

TCP传输

Socket和ServerSocket
建立客户端和服务器端
建立连接后,通过Socket中的IO流进行数据的传输
关闭socket
同样,客户端与服务器端是两个独立的应用程序。

类加载器和反射 反射

反射:通过一个Class文件对象去使用改文件对象中的成员变量,构造方法,成员方法

class类:
成员变量:Field
构造方法:Constructor
成员方法:Method

如何获取一个类对应的Class文件对象呢?
1、通过Object类中的getClass()方法,返回此Object的运行时类
2、在不new对象的前提下,获取该类的class文件对象,使用类的静态属性class来获取

public class ReflexDemo1 { public static void main(String[] args) { //方式1:通过Object类中的getClass()方法,返回此Object的运行时类 Person p = new Person(); Class<? extends Person> c1 = p.getClass(); Person p2 = new Person(); Class<? extends Person> c2 = p.getClass(); System.out.println(c1==c2); //方式2:在不new对象的前提下,获取该类的class文件对象,使用类的静态属性class来获取 Class c3 = Person.class; System.out.println(c1==c3); System.out.println(c2==c3); //方式3:public static Class<?> forName(String className) //返回与给定字符串名称的类或接口相关联的类对象。 调用此方法相当于: try { Class<?> c4 = Class.forName("com.shujia.wyh.day27.Person"); System.out.println(c1==c4); System.out.println(c2==c4); } catch (ClassNotFoundException e) { e.printStackTrace(); } }}

如何通过反射获取Class文件对象中的构造方法并使用呢?

public class ReflexDemo2 { public static void main(String[] args) throws Exception { //获取Class文件对象 Class<?> c1 = Class.forName("com.shujia.wyh.day27.Person"); //获取构造方法,只能获取所有的公共的构造方法 //public Constructor<?>[] getConstructors() //返回一个包含Constructor对象的数组, Constructor<?>[] cons = c1.getConstructors(); for(Constructor c : cons){ System.out.println(c); } System.out.println("=========================================="); //public Constructor<?>[] getDeclaredConstructors() //返回反映Constructor对象表示的类声明的所有Constructor对象的数组类 //获取所有的构造方法,包括私有,被保护的,默认的,公共的 Constructor<?>[] cons2 = c1.getDeclaredConstructors(); for(Constructor c: cons2){ System.out.println(c); } System.out.println("=========================================="); //获取单个构造方法 //public Constructor getConstructor(类<?>..、parameterTypes) //返回一个Constructor对象,该对象反映Constructor对象表示的类的指定的公共类函数。// Constructor<?> con = c1.getConstructor(); //相当于获取无参构造方法// System.out.println(con); Constructor<?> con = c1.getConstructor(String.class); System.out.println(con);// Constructor<?> con = c1.getDeclaredConstructor(String.class, int.class);// System.out.println(con); System.out.println("==========================================="); //public T newInstance(Object..、initargs) //使用由此Constructor对象表示的构造函数,使用指定的初始化参数创建和初始化构造函数的声明类的新实例。// Object o = con.newInstance("你好",23);// System.out.println(o); Person p = (Person)con.newInstance("1001"); System.out.println(p); }}

通过反射获取私有的构造方法并创建对象

public class ReflexDemo3 { public static void main(String[] args) throws Exception { //获取类的字节码文件对象 Class<?> c1 = Class.forName("com.shujia.wyh.day27.Person"); //获取私有的构造方法 Constructor<?> con = c1.getDeclaredConstructor(String.class, int.class); System.out.println(con); //IllegalAccessException 非法的访问异常 //暴力访问 con.setAccessible(true); //这里的值如果时true的话,表示反射的对象在使用的时候取消Java语言的访问检查 //使用Constructor类中的方法来创建对象 Object o = con.newInstance("明旺", 18); Person p = (Person) o; System.out.println(p); }}

通过反射获取成员变量并使用

public class ReflexDemo4 { public static void main(String[] args) throws Exception { //1、获取字节码文件对象 Class<?> c1 = Class.forName("com.shujia.wyh.day27.Person"); //获取所有的公共成员变量 //public Field[] getFields() //返回包含一个数组Field对象反射由此表示的类或接口的所有可访问的公共字段类对象。 Field[] fields = c1.getFields(); for (Field f : fields) { System.out.println(f); } System.out.println("=========================================="); //public Field[] getDeclaredFields() //获取当前类中所有成员变量 //返回的数组Field对象反映此表示的类或接口声明的所有字段类对象。 //这包括公共,受保护,默认(包)访问和私有字段,但不包括继承的字段。 Field[] fields2 = c1.getDeclaredFields(); for (Field f : fields2) { System.out.println(f); } System.out.println("========================================="); //获取无参构造方法,然后利用反射给成员变量赋值 Constructor<?> con = c1.getConstructor(); //创建对象 Object o = con.newInstance(); System.out.println(o); System.out.println("========================================="); //获取单个成员变量 Field id = c1.getField("id"); //将指定对象上的成员变量付上一个新的值 //void set(Object obj, Object value) //将指定对象参数上的此 Field对象表示的字段设置为指定的新值。 id.set(o,"1002"); System.out.println(o); System.out.println("=========================================="); //反射获取私有的成员变量并赋值 //NoSuchFieldException// Field name = c1.getField("name");// System.out.println(name); Field name = c1.getDeclaredField("name"); System.out.println(name); //暴力访问 name.setAccessible(true); name.set(o,"王宇"); System.out.println(o); System.out.println("=========================================="); //获取被protected修饰的成员变量,不需要暴力访问 Field address = c1.getDeclaredField("address"); address.set(o,"安徽合肥"); System.out.println(o); System.out.println("=========================================="); //获取默认的修饰符修饰的成员变量并赋值,不需要暴力访问 Field age = c1.getDeclaredField("age"); age.set(o,19); System.out.println(o); }}

通过反射获取成员方法并使用

public class ReflexDemo5 { public static void main(String[] args) throws Exception { //1、获取字节码文件对象 Class<?> c1 = Class.forName("com.shujia.wyh.day27.Person"); //获取方法 //public 方法[] getMethods() //获取本类中的公共方法和父类中所有的公共方法 //返回包含一个数组方法对象反射由此表示的类或接口的所有公共方法类对象,包括那些由类或接口和那些从超类和超接口继承的声明 Method[] methods = c1.getMethods(); for (Method m : methods) { System.out.println(m); } System.out.println("========================================="); Method[] methods2 = c1.getDeclaredMethods(); //获取自己的所有的方法,包括私有,不能获取父类的 for (Method m : methods2) { System.out.println(m); } System.out.println("========================================="); //获取单个方法并调用 Method fun1 = c1.getMethod("fun1"); Constructor<?> cons = c1.getConstructor(); Object o = cons.newInstance(); //public Object invoke(Object obj,Object..、args) //在具有指定参数的方法对象上调用此方法对象表示的基础方法。 //第一个参数指的是调用方法的对象,第二个参数指的是实际需要传入的数据(实参) fun1.invoke(o); System.out.println("========================================");// Method fun2 = c1.getMethod("fun2", String.class);// System.out.println(fun2); Method fun2 = c1.getDeclaredMethod("fun2", String.class); //暴力访问 fun2.setAccessible(true); //只有私有的方法调用需要暴力访问 fun2.invoke(o,"数加科技"); System.out.println("========================================="); Method fun3 = c1.getDeclaredMethod("fun3"); Object invoke = fun3.invoke(o); System.out.println("========================================="); Method fun4 = c1.getDeclaredMethod("fn4"); fun4.invoke(o); }}

反射小练习

通过配置文件运行类中的方法

配置文件:
配置文件里面基本上都是键–值这样的键值存在的
className
com.shujia.wyh.day27.Person

public class ReflexTest1 { public static void main(String[] args) throws Exception { //在学习反射之前// Person person = new Person();// person.fun1();// person.fun2(); //学习反射之后 Properties prop = new Properties(); FileReader fr = new FileReader("D:\IdeaProjects\bigdata15\src\com\shujia\wyh\day27\configure.txt"); prop.load(fr); fr.close(); //获取数据 String className = prop.getProperty("className"); System.out.println(className); String methodName = prop.getProperty("methodName"); System.out.println(methodName); //通过反射实现 Class<?> c1 = Class.forName(className); Constructor<?> cons = c1.getConstructor(); Object o = cons.newInstance(); //通过反射调用方法 Method fun2 = c1.getDeclaredMethod(methodName, String.class); //暴力访问 fun2.setAccessible(true); fun2.invoke(o,"数加科技,yyds"); }}

我给你ArrayList的一个对象,我想在这个集合中添加一个字符串数据,如何实现呢?

public class ReflexTest2 { public static void main(String[] args) throws Exception { ArrayList list = new ArrayList<>();// list.add(10);// list.add("你好"); //通过反射实现 Class<? extends ArrayList> listClass = list.getClass(); Method add = listClass.getMethod("add", Object.class); add.invoke(list,20); add.invoke(list,"你好"); add.invoke(list,12.34);// for(Integer i:list){// System.out.println(i);// } Iterator iterator = list.iterator(); while (iterator.hasNext()){ Object next = (Object)iterator.next(); System.out.println(next); } }}

动态代理

代理:本来应该自己做的事情,却请了别人来做,被请的人就是代理对象。
举例:春季回家买票让人代买
动态代理:在程序运行过程中产生的这个对象
而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以,动态代理其实就是通过反射来生成一个代理

在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象。JDK提供的代理只能针对接口做代理。我们有更强大的代理cglib
Proxy类中的方法创建动态代理类对象
Object invoke(Object proxy,Method method,Object[] args)public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
最终会调用InvocationHandler的方法
InvocationHandler

总复习以及后面的规划

一:初识Java1、什么是计算机2、DOS3、Java4、JDK,JRE,JVM5、安装JDK6、配置环境变量7、HelloWorld8、java运行步骤二、Java基础语法1、注释2、关键字3、标识符4、常量5、运算符 + = == || && 三目运算符6、键盘录入7、语法结构8、变量9、方法和数组三、面向对象封装继承多态四、常用类ObjectStringStringBuffer、StringBuilderArrays自定义工具类 文档注释五、集合CollectionMap六、IO异常File递归字节流字符流序列化流七、多线程三种实现线程方式解决线程同步安全问题的方案: 1、synchronized关键字 2、lock锁死锁等待唤醒机制线程池(了解几种线程池的区别即可)八、网络编程UDPTCP九、反射(将上课的案例看懂敲会即可)今后的学习路线:LinuxMySql on LinuxSpringboot结合mysql实现数据增删改查在页面显示redishadoophive(每天练习至少2道hive题)hbase...

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。