*****【第二十四天】反射、数据库和VIP用户的解耦实例、Junit测试库、Annotation注解、元注解
复习:
1. 网络编程:网络基本概念;
地址类 --- InetSocketAddress;
UDP --- 基于流的。不建立连接,不可靠。传输速度相对较快,要对数据进行封包,每个包不超过64K。发送端和接收端 --- DatagramSocket,DatagramPacket;
TCP --- 基于流的。建立连接,经过三次握手,可靠。传输速度相对较慢。不限制数据的大小。客户端(Socket)和服务器端(ServerSocket)
反射
Class --- 代表字节码的类 --- 代表类的类
Field --- 代表属性的类
Method --- 代表方法的类
Constructor --- 代表构造方法的类
Annotation --- 代表注解的类
Package --- 代表包的类
反射就是在剖析一个类,了解这个类的构造,创建这个类对应的对象
如何获取一个Class对象?
1. 通过类名.class 的方式来获取对应的类的字节码对象
// 通过类名.class的方式来获取一个字节码对象 // clz表示的就是String的字节码 Class<String> clz = String.class; System.out.println(clz); // clz2表示的就是List的字节码 Class<List> clz2 = List.class; System.out.println(clz2); // clz3表示的就是String[]的字节码 Class<String[]> clz3 = String[].class; System.out.println(clz3); // clz4表示的就是int的字节码 Class clz4 = int.class; System.out.println(clz4);
2. 通过对象.getClass()的方式来获取这个对象对应的实际类的字节码对象
Object str = "abc"; Class<String> clz5 = (Class<String>) str.getClass(); System.out.println(clz5);
3. 通过Class.forName(类的全路径名)的方式来获取指定的类的字节码对象
Class<String> clz6 = (Class<String>) Class.forName("java.lang.String"); System.out.println(clz6); Class<List> clz7 = (Class<List>) Class.forName("java.util.List"); System.out.println(clz7);
为什么说java是一门完全面向对象的语言?--- 因为类本身也是对象
int i = 5;
i = i + 3;
Junit测试库(不用写主函数就能运行函数)
单元测试---要求 “三无” --- 没有参数(如果要测试的方法有参数可以把它放到一个无参的函数里面再测试),没有返回值(void),不是静态的(not static)
package cn.tedu.test; import org.junit.After; import org.junit.Before; import org.junit.Test; public class TestDemo { private int i; @After public void mb() { System.out.println("关流~~~"); } @Before public void ma() { i = 5; } public int add(int i, int j) { return i + j; } @Test public void m() { System.out.println(add(i, 5)); System.out.println("hello~~~"); } @Test public void m2() { System.out.println(i); System.out.println("test~~~"); } }
Annotation---注解(本质上是一个接口)
配置文件很好,但是配置文件太多会让程序的大量时间花费在配置文件上,一些简单的配置就可以放到代码中让代码来实现
@interface Anno{} 注解的定义方式
实现一些轻量级的配置(porperties)。
@Override --- 标志一个重写的方法
@Deprecated --- 标志过时
@SuppressWarnings --- 压制警告
注解中的属性允许:基本类型,String,Class,其他注解,枚举(enumeration)以及上述类型的一维数组形式
如果注解中只有一个属性必须赋值,而且这个属性的名字为value,那么在赋值的时候value = 可以不写。
如果赋值的时候一维数组中只有一个值,那么{}可以省略不写
元注解---可以作用在注解上的注解(限制注解的范围)
@Target---限制注解的使用范围 Target(ElementType.METHOD/FIELD/PARAMETER/CONSTRACTER/LOCAL_VARIABLE)
@Retention --- 限制注解的使用周期的(从时间上限制)
@Documented --- 让注解出现在文档中
@Inherited --- 表示此注解会随着继承作用到子类上
注意 : @Documented使用方法:在一个新的类的方法前加上@Anno,然后选中@Anno -> Project菜单->Generate JavaDoc->选择工程然后选中所有finish->Yes To All->右击工程文件然后右击refresh,就会生成Doc文档,选择resource。去工作空间找一下 doc文件夹里面的index.html之前的所有文件都在 而person类中没有出现Anno注解,要想在文件中显示Anno就去最开始的class里写@Documented后Anno就会在index.html显示
package cn.tedu.test; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; public class AnnotationDemo { } // @Anno(name = "Amy", count = 5, price = { 2, 1.3, 6.4 }) // @Anno({ 5.2, 2.3 })
// @Anno(value={{5.2,2.3})(可以省略) // @Anno(arr = { 5, 3 }) class Demo { @SuppressWarnings("unused") @Annopublic void m(@Anno int i) { @Anno int j = 0; } } @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @interface Anno {// 属性count的默认值为7 int count() default 7;//加() 但是不是方法 // int[] arr(); // double[] value(); // String name(); // Object obj(); // double[] price(); }
jdk8的部分特性
接口中的默认方法、Lambda表达式、方法的传递、函数式接口、Stream、时间包、final的作用域
**:JVM的运行参数
new Thread(new Runnable(){
public void run(){
System.out.println(“hahah~~~”);
}
}).start();
new Thread(() -> System.out.println(“hahah~~~”)).start();