单元测试&注解&反射
JUnit单元测试
作用
-
可以选择性的决定测试哪些功能,也可以把所有功能都测试
-
不会因为一个功能出现问题,影响其他功能的测试
-
测试结果是有报告,这个标记是长久保留的,过两天可以继续过来解决
-
提供了断言测试,针对一些不报错,但是业务逻辑有问题的测试
### 使用步骤
-
导包
-
针对要测试的功能,编写测试类和测试方法
-
测试方法要求
-
方法要加上@Test注解,给了一个标记,告诉框架哪些方法需要测试
-
测试方法必须是公共、无参数、无返回值、非静态的方法
-
-
断言测试
-
Assert.assertEquals("错误提示信息", 预期结果, 实际结果)
-
常用注解
-
@Test
-
JUnit4版本
-
@Before
-
每一个测试方法执行之前,都会执行一次
-
-
@After
-
每一个测试方法执行之后,都会执行一次
-
-
@BeforeClass
-
所有测试方法执行之前,只执行一次
-
-
@AfterClass
-
所有测试方法执行之后,只执行一次
-
-
反射
作用
-
在运行的时候,拿到一个类的全部信息
-
经常用来做一些框架的底层技术,因为制作框架的时候,不知道未来有哪些类需要使用
步骤
-
第一步:拿到一个类字节码对象(Class对象)
-
Class.forName("类的全限定名")
-
类名.class
-
对象.getClass()
-
-
第二步:通过Class对象获取这个类中各个成员
-
构造器:Constructor
-
成员变量:Field
-
成员方法:Method
-
-
第三步:操作类中的各个成员
-
Constructor对象
-
可以用来创建一个类的对象:newInstance(参数值)
-
-
Field对象
-
可以给属性赋值和取值:field.set(对象,值);field.get(对象);
-
-
Method对象
-
可以调用方法:method.invoke(对象,方法参数值,...)
-
-
注意:如果操作的构造器/成员变量/成员方法被private修饰,在操作之前需要开启访问权限:setAccessible(true);
-
注解
作用
-
给程序的一些内容加标记!
-
加完标记之后,可以进行解析,然后再根据不同的需求,执行不同的业务逻辑
JDK内置注解
-
@Override
-
检测方法重写的正确性
-
-
@FunctionalInterface
-
检测接口是否是函数式接口
-
-
@Deprecated
-
标记一些方法已经过时,未来可能需要删除
-
-
@SupressWarnnings
-
压制警告
-
自定义注解
-
格式
-
public @interface 注解名{ public 属性类型 属性名() default 默认值; }
-
-
特殊属性
-
value
-
如果有且仅有一个必须要赋值且名称叫value的属性,在给value属性赋值时可以省略value名称不写!!
-
-
元注解
-
作用
-
修饰注解的注解
-
-
常用
-
@Target
-
作用
-
限制你的注解能修饰哪些地方
-
-
-
@Rentention
-
作用
-
限制你的注解能保留到什么时候
-
-
常用的作用范围
-
RententionPolicy.RUNTIME
-
-
-
注解解析
-
获取成份上所有的注解对象
-
getDeclaredAnnotations()
-
-
获取成份上指定的注解对象
-
getDeclaredAnnotation(指定注解的字节码对象)
-
-
判断成份上是否使用过指定的注解
-
isAnnotationPresent(指定注解的字节码对象)
package 反射与注解.test01; public class Computer { public void playGame(){ System.out.println("反方向的钟"); } }
-
package 反射与注解.test01; public class Computer { public void playGame(){ System.out.println("反方向的钟"); } }
package 反射与注解.test01; @config(classname = "反射与注解.test01.Computer",methodname = "playGame") public class Myconfig { }
package 反射与注解.test01; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class test { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { //1、获取Myconfig字节码文件 Class<Myconfig> clazz1 = Myconfig.class; //2、通过字节码获取Myconfig类上面的注释 config config = clazz1.getDeclaredAnnotation(config.class); //3、获得注释的属性 String classname = config.classname(); String methodname = config.methodname(); //4、通过classname获得类的字节码文件 Class<?> aClass = Class.forName(classname); //5、获得运行方法 Method method1 = aClass.getDeclaredMethod(methodname); //6、执行方法 Object o = aClass.getConstructor().newInstance(); method1.invoke(o); } }
网络编程
1、网络编程三要素
1、IP地址
-
1、作用:
-
找到对方在网络上的计算机,所以ip其实就是一个网络地址
-
-
2、分类:
-
ipv4
-
32bit
-
点分十进制
-
通常以192.168开头的地址都是局域网地址
-
-
ipv6:
-
128bit
-
冒分十六进制
-
"号称可以给地球上每一个沙子分配一个ip地址"
-
-
-
3、常用命令:
-
1、查看本机ip: ipconfig
-
2、查看ip是否连通: ping ip地址
-
2、端口号:
-
1、作用:
-
光找到对方的计算机还不行,得知道跟那个计算机的那个程序沟通,所以端口号就代表对方计算机那个程序
-
-
2、范围:
-
0~65535
-
周知端口
-
0~1023
-
已经被用,不能自己用
-
-
注册端口
-
1024~49151
-
也有一些常用的程序占用
-
tomcat服务器程序占用了8080
-
-
-
动态端口:
-
其他的
-
用来随机分配的端口号
-
-
-
3、通信协议:
-
1、传输层协议:
-
1、tcp
-
1、面向连接、安全的协议
-
2、效率稍差
-
3、适用于一些对数据安全要求高的场景,eg:文件下载
-
-
2、udp:
-
1、面向无连接、不安全的协议
-
2、效率高
-
3、一次最多传64kb
-
4、容易丢失数据
-
5、是用于对数据安全要求不高,eg:视频通话、语音通话
-
-
-
2、tcp协议:
-
建立
-
三次握手
-
确认两边既可以收也可以发
-
-
-
断开
-
4次挥手
-
确认两边都准备好断开,并且把一些收尾工作做完
-
-
-
2、UDP
1、发送和接收数据的对象
-
DategramSocket对象
-
客户端
-
创建对象的时候不需要指定端口号,会随机分配一个
-
-
服务端
-
创建对象的时候需要指定一个端口号,需要让客户端发过来
-
2、把数据打包
-
1、DatagramPacket对象
-
2、客户端
-
需要发数据
-
1、发送的数据
-
2、发送数据的长度
-
3、发给谁,对象的IP地址
-
4、发给对方电脑上的那个程序,端口号
-
-
-
3、服务端
-
把收到的数据打包
-
接受数据的长度
-
-
3、发和收的方法:
-
发
-
send(数据包对象)
-
-
收
-
receive(数据包对象)
-
4、获取收到的数据:
-
数据包对象调用getData().拿到收到的字节数据的数组
5、获取收到的字节数据的个数
-
数据包对象调用get.length()
package 网络编程.UDP创建发送端与接收端; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class ClientDemo { public static void main(String[] args) throws IOException { //1、创建DatagramSocket接收端对象 DatagramSocket socket = new DatagramSocket(10086); //2、封装 byte[] bytes = new byte[1024 * 8]; DatagramPacket packet = new DatagramPacket(bytes, bytes.length); //3、接收 socket.receive(packet); //4、解析 int length = packet.getLength(); String s = new String(bytes, 0, length); System.out.println(s); //5、关闭 socket.close(); } }
package 网络编程.UDP创建发送端与接收端; import java.io.IOException; import java.net.*; public class SeverDemo { public static void main(String[] args) throws IOException { //1、创建一个DatagramSocket发送端对象 DatagramSocket socket = new DatagramSocket(); //2、封装数据 byte[] bytes = "你甚至不愿喊我一声教父".getBytes(); DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("192.168.73.58"), 10086); //3、发送数据 socket.send(packet); //4、关闭 socket.close(); } }
TCP
1、发送数据的对象
-
1、Socket对象
-
2、创建的时候需要指定服务端ip和服务端程序的端口
2、接收数据的对象
-
1、SeverSocket对象
-
2、可以获取不同客户端请求过来的连接
3、获取到不同客户端请求过来的连接对象
-
accept()
4、客户端往服务器写数据
-
1、利用Socket对象拿到输出流,用输出流往外写,记得刷新
-
2、不写的时候,记得释放资源,底层自动开启4次挥手
-
3、利用Socket对象拿到输入流,利用输入流从网络中获取数据往服务端程序内部写入
5、服务端接收客户端数据
-
利用Socket对象拿到输入流,利用输入流从网络中获取数据往服务端程序内部写入
6、优化服务端
-
开线程
-
当有一个客户端连接过来的时候,就开启一个子线程处理,不影响主线程继续accept()
-
-
线程池
-
1、不断地开线程,系统容易崩,所以不手动开线程,利用线程池提交任务
-
2、暂时无法处理的任务,会到队列中等待
package 网络编程.TCP创建发送端与接收端; import java.io.*; import java.net.Socket; public class Client { public static void main(String[] args) throws IOException { System.out.println("客户端启动~"); //1、创建Scock对象与服务器连接 Socket socket = new Socket("192.168.73.58",10067); //2、将获取的字节数据转换为字符输出流,用于往服务端口写数据 OutputStream os = socket.getOutputStream(); OutputStreamWriter osw = new OutputStreamWriter(os); BufferedWriter bw = new BufferedWriter(osw); //3、获取字符输入流,写一行换一行 bw.write("你看世界杯了吗?"); bw.newLine(); bw.flush(); //4、提醒写入结束 socket.shutdownOutput(); //5、通过socket获取文件读取信息,接受服务器发送的信息 InputStream is = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line = br.readLine(); System.out.println(line); //关闭通道 socket.close(); } }
-
package 网络编程.TCP创建发送端与接收端; import java.io.*; import java.net.ServerSocket; import java.net.Socket; public class Sever { public static void main(String[] args) throws IOException { System.out.println("服务器端启动~"); //1、建立客户端与服务器端连接,创建ServerSocket对象,绑定端口 ServerSocket serverSocket = new ServerSocket(10067); //2、监听客户端连接,并获取它 Socket socket = serverSocket.accept(); //3、通过socket获取字节输入流,用于获取读取客户端发过来的信息 InputStream is = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line = br.readLine(); System.out.println(line); //4、通过socket获取字节输出流,反馈给客户端信息 OutputStream os = socket.getOutputStream(); OutputStreamWriter osw = new OutputStreamWriter(os); BufferedWriter bw = new BufferedWriter(osw); bw.write("阿根廷夺冠了!!!"); bw.newLine(); bw.flush(); socket.shutdownOutput(); socket.close(); serverSocket.close(); } }