JAVA高级(二)
1. 正则表达式
-
作用:
- 用来校验数据格式是否合法
- 在一段文本中查找满足需求的内容
-
书写规则:
2. 集合框架(一)
- 集合体系结构
- Collection单列集合
- Map双列集合(键值对)

- Collection的遍历方式:
- 迭代器Iterator
- 增强for循环:可以用来遍历数组或者集合(本质是迭代器的简化写法)
Collection<String> c = new ArrayList<>(); c.add("alex"); Iterator<String> it = c.iterator(); while(it.hasNext()){ String ele = it.next(); }
for(String ele : c){ System }
c.forEach(new Consumer<String>(){ @Override public void accept(String s){ System.out.println(s); } }); c.forEach((String s)->{ System.out.println(s); } ); c.forEach(s->{ System.out.println(s); }); c.forEach(System.out::println);
|
- List集合:有序、可重复、有索引
- ArrayList集合特点
- 基于数组实现
- 查询效率低
- 删除效率低
- 添加效率极低
- LinkedList(双向链表)
- 查询慢(需要从开始查)
- 增删相对快
- 双向列表对首位元素进行增删改查的速度极快。
- 应用场景:可以用来设计栈
List<String> list = new ArrayList<>(); list.add("121"); list.add("232"); list.add(1,"222"); list.remove(2); list.get(1); list.set(1,"zz");
LinkedList<String> queue = newe LinkedList<>(); queue.addLast("1"); queue,addLast("2"); queue.removeFirst();
|
- Set集合:无序、不重复、无索引
- HashSet:无序、不重复、无索引
- LinkedHashSet:有序、不重复、无索引
- 原理:每个元素额外多了一个双链表机制记录前后元素的位置
- TreeSet:排序、不重复、无索引、可排序(基于红黑树实现)

Iterator<String> it =list.iterator(); while(it.hasNext()){ String name = it.next(); if(name.contains("李")){ list.remove(name); it.remove() }
|
3. 集合框架(二)
- 可变参数:
- 一种特殊的形参,可以不传数据给他;可以传一个或者多个数据给他,也可以传一个数组;可以更灵活的接收数据。
public static void test(int...nums){};
List<String> names = new ArrayList<>(); Collections.addAll(names,"zz","zhw","www"); Collections.shuffle(names); List<Integer> list = new ArrayList<>(); list.add(3); list.add(4); Collections.sort(list);
Collections.sort(Students,( o1, o2) -> Double.compare(o1.getHeight(),o2.getHeight()));
|
-
Map系列集合
-
特点:
Map<String,Integer> map = new HashMap<>(); map.put("手机",100); map.put("手表",200); Map<Integer, String> map1 = new TreeMap<>();
|
-
Map的常用方法:
map.size(); map.clear(); map.isEmpty(); int v1 = map.get("手表"); map.remove("手表"); map.containsKey("手机"); map.containsValue(2); Set<String> keys = map.keySet(); Collection<Integer> values = map.values(); map1.putAll(map2);
|
-
Map的遍历
Map<String, Double> map = new HashMap<>(); map.put("zz",188.5); map.put("xx",177.6); map.put("cc",177.9); Set<String> keys = map.keySet(); System.out.println(keys); for(String key : keys){ double value = map.get(key); System.out.println(key+" "+value); }
Set<Map.Entry<String, Double> >entries = map.entrySet(); for(Map.Entry<String,Double> entry : entries){ String key = entry.getKey(); double value = entry.getValue(); System.out.println(key+" "+value); }
map.forEach((k,v) ->{ System.out.println(key+" "+value); });
|
Map<Student, String> map = new TreeMap<>(new Comparator<Student>(){ @Override public int compare(Student o1,Student o2){ return Double.compare(o2.getHeight(),o1.getHeight()); } }); System.out.println(map);
|

- Stream 流
- 定义:
- 可以用来操作集合或者数组的数据
- 结合了Lambda的语法风格编程,代码更简洁,可读性更好
List<String> names = new ArrayList<>(); Collections.addAll(names,"zz","zs","zd","sd"); List<String> list2 = names.stream().filter(s -> s.startsWith("z")).filter(a->a.length() == 2).collect(Collectors.toList()); System.out.println(list2);
|
Set<String> set = new HashSet<>(); Collections.addAll(set,"zz","zs","zd","sd"); Stream<String> stream1 = set.stream(); stream1.filter(s -> s.contains("z")).forEach(s -> System.out.println(s));
Map<String,String> map = new HashMap<>(); map.put("zz",188.5); map.put("xx",177.6); map.put("cc",177.9);
Set<String> keys = map.keySet(); Stream<String> ks = keys.stream(); Collection<Double> values = map.values(); Stream<Double> vs = values.stream();
Set<Map.Entry<String, Double>> entries = map.entrySet(); Stream<Map.Entry<String, Double>> kvs = entries.stream(); kvs.filter(e ->e.getKey().contains("z")).forEach(e -> System.out.println(e.getKey()));
String[] names = {"zza","zz","as"}; Stream<String> s1 = Arrays.stream(names2); Stream<String> s2 = Stream.of(names2);
|
List<Double> scores = new ArrayList<>(); Collections.addAll(scores,88.5,75.2,12.54,12.3,98.5,2.0); scores.stream().filter(s -> s >=60).sorted().forEach(s -> System.out.println(s));
List<Student> students = new ArrayList<>(); students.stream().filter(s -> s.getAge() >=23 && s.getAge() <= 30).sort((o1,o2) -> o2.getAge() - o1.getAge()).forEach(s -> System.out.println(s));
students.stream().sort((o1,o2) -> Double.compare(o2.getHeight(),o1.getHeight()).limit(3).forEach(s -> System.out.println(s));
students.stream().sorted((o1,o2)->Double.compare(o2.getHeight(),o1.getHeight())).skip(students.size()-2).forEach(s -> System.out.println(s));
students.stream().filter(s -> s.getHeight()>168).map(s ->s.getName()).distinct().forEach(s -> System.out.println(s));
Stream<String> st1 = Stream.of("zz","xx"); Stream<String> st2 = Stream.of("zz1","xx1"); Stream<String> st3 = Stream.concat(st1,st2); allSt.forEach(System.out::println);
|
- Stream流的终结方法
- 终结方法指的是调用完成后,不会返回新的Stream了,没法再继续使用流了
long size = students.stream().filter(s -> s.getHeight() > 168).count(); System.out.println(size);
students.stream().max((o1,o2) -> Double.compare(o1.getHeight(),o2.getHeight()));
List<Student> students1 = students.stream().filter(s -> s.getHeight > 170.0).collect(Collectors.toList()); Set<Student> students2 = students.stream().filter(s -> s.getHeight > 170.0).collect(Collectors.toSet());
Map<String, Double> map = students.stream().filter(a -> a.getHeight()>170).distinct().collect(Collectors.toMap(a ->a.getName,a->a.getHeight())); Object[] arr = students.stream().filter(a -> a.getHeight()>170).toArray(); Student[] arr = students.stream().filter(a -> a.getHeight()>170).toArray(len -> new Student[len]);
|
4. File、IO流
4.1 概述
File类的对象,用于代表当前操作系统的文件(文件、文件夹)。
File类只能对文件本身进行操作,不能读写文件里面存储的数据。
IO流:用于读写数据的(可以读写文件,或网络中的数据…)
File f1 = new File("D:/resource/ab.txt"); File f1 = new File("D:"+File.separator+"resource"+File.separator+"ab.txt"); System.out.println(f1.length()); File f2 = new File("D:/resource"); File f3 = new File("D/resource//aaa.txt"); System.out.println(f3.exists());
|
4.2 File操作方法
File f3 = new File("D/resource//aaa.txt"); System.out.println(f3.exists()); System.out.println(f3.isFile()); System.out.println(f3.isDirectory()); System.out.println(f3.getName()); long time = f3.lastModified(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); System.out.println(sdf.format(time)); f3.getPath(); f3.getAbsolutePath();
|
File f1 = new File("D/resource//aaa.txt"); boolean flag = f1.createNewFile(); File f2 = new File("D:/resource/aaa/bbb"); System.out.println(f2.mkdir()); System.out.println(f2.mkdirs()); System.out.println(f1.delete()); System.out.println(f1.delete());
|
- 遍历文件夹
- 注意事项:
- 当主调是文件,或者路径不存在,返回null
- 当主调是空文件夹。返回空数组
- 当没有权限时,返回null
File f1 = new File("D/resource"); String[] names = f1.list(); for(String name : names){ System.out.println(name); } File[] files = f1.listFiles(); for(File file : files){ System.out.println(file.getAbsolutePath()); }
|
File root = new File("D:/"); public static void searchFile(File dir, String fileName){ if(dir == null || !dir.exists()!! dir.isFile()){ return; } File[] files = dir.listFiles(); if(files != null && files.length >0){ for(File f :files){ if(f.isFile()){ if(f.getName().contains(filename)) System.out.println("找到了"+ f.getAbsolutePath()); }else{ searchFile(f, fileName); } } } }
|
4.3 字符集
- 常见字符集
- ASCII字符集:使用一个字节存储一个字符,首位为0。
- GBK(汉字内码扩展规范):GBK中一个中文字符编码为两个字节的形式存储。规定:第一个字节的第一位必须为1。
- Unicode字符集(统一码,国际组织制定,可以容纳世界上所有文字、符号的字符集)。
- UTF-8:可变长编码方案。英文、数字占一个字节,汉字字符占3个字节。
4.4 IO流
- 概述:I为输入流,负责把数据读到内存中,O为输出流,负责写数据出去。
- 分类:字节输入/输出流、字符输入/输出流。

InputStream is = new FileInputStream(new File("file-io-app\\src\\001.txt")); InputStream is = new FileInputStream("file-io-app\\src\\001.txt"); int b1 = is.read(); System.out.println((char)b1); int b2 = is.read(); System.out.println((char)b2); int b3 = is.read(); System.out.println((char)b3);
is.close();
|
- FileInputStream(文件字节输入流)读取多个字节
InputStream is = new FileInputStream(new File("file-io-app\\src\\001.txt"));
byte[] buffer = new byte[3]; int len = is.read(buffer); String rs = new String(buffer); int len2 = is.read(buffer); String rs2 = new String(buffer, 0 ,len2);
byte[] buffer = new byte[3]; int len; while((len = new String(buffer,0,len)) !=-1){ String rs = new String(buffer,,0,len); System.out.println(rs); }
byte[] buffer = is.readAllBytes(); System.out.print(new String(buffer));
|
- FileOutputStream(文件字节输出流)
OutputStream os = new FileOutputStream("file-io-app/src/002.txt");
OutputStream os = new FileOutputStream("file-io-app/src/002.txt", append = true); os.write(97); os.write("b"); byte[] bytes = "我爱你中国abc".getBytes(); os.write(bytes); os.write(bytes,0,15); os.write("\r\n".getBytes()); os.close();
|
InputStream is = new FileInputStream("D:/resource/meinv.png"); OutputStream os = new FileOutputStream("C:/data/meinv2.png"); byte[] buffer = new byte[1024]; int len ; while((len = is.read(buffer))!=-1){ os.write(buffer,0,len); } os.close; is.close;
|
- 释放资源的方式
- finally代码区的特点:无论try中的程序是正常执行或是出现异常,最后一定会执行finally区,除非JVM终止
- try-with-resource
try{ System.out.println(10/2); return; }catch(Exception e){ e.printStackTrace(); }finally{ System.out.println("执行"); } try{ return a/b; }catch(Exception e){ e.printStackTrace(); return -1; }finally{ System.out.println("执行"); return 111; }
|
InputStream is =null; OutputStream os =null; try {
System.out.println(10/0); is = new FileInputStream("aaa.txt"); os = new FileOutputStream("bbb.txt"); System.out.println(10/0); byte[] buffer = new byte[2024]; int len; while((len = is.read(buffer))!=-1){ os.write(buffer,0,len); } System.out.println("完成"); } catch (IOException e) { e.printStackTrace(); } finally { if(os != null){ try { os.close(); } catch (IOException e) { e.printStackTrace(); } } if(is!=null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } }
|
try( InputStream is = new FileInputStream("aaa.txt"); OutputStream os = new FileOutputStream('bbb,txt'); ) { byte[] buffer = new byte[2024]; int len; while ((len = is.read(buffer)) != -1) { os.write(buffer, 0, len); } System.out.println("完成"); }catch (Exception e){ e.printStackTrace(); }
|
4.5 字符流
- 作用:以内存为基准,可以把文件中的数据以字符的形式读入到内存中去。
try(Reader fr = new FileReader("aaa.txt");){ int c; while((c=fr.read())!=-1){ System.out.print(c); } char[] buffer = new char[3]; int len; while((len = fr.read(buffer))!=-1){ System.out.print(new String(buffer,0,len)); } }catch (Exception e){ e.printStackTrace(); }
|
try(Writer fw = new FileWriter("111.txt");){ fw.write('a'); fw.write(97); fw.write('一'); fw.write("我爱你中国abc",0,5); char[] buffer = {'a','b','c','d'}; fw.write(buffer); fw.write(buffer, 0, 2); fw.write("\r\n"); }catch(Exception e){ e.printStackTrace(); }
|
- 字符输出流写出数据后,必须刷新流,或者关闭流,写出去的数据才能生效。
- 字节流适合做一切文件数据的拷贝;字节流不适合读取中文内容输出
- 字符流适合做文本文件的(读写)
5. IO的各种流
5.1 IO流-缓冲流

- 对原始流进行包装,一提高原始流读写数据的性能
- BufferedReader、BufferedWriter自带8K缓冲池,可以提高字符输出流写字符数据的性能。(最好不要用多态写)
InputStream is = new FileInputStream("aaa.txt"); InputStream bis = new BufferedInputSystem(is); OutputStream os = new FileOutputStream('bbb,txt'); OnputStream bos = new BufferedOutputSystem(os);
Reader fr = new FileReader("aaa.txt"); BufferedReader br = new BufferedReader(fr); String line; while((line = br.readline)!=null){ System.out.println(line); }
bw.newline();
|
5.2 IO转换流
-
解决问题:被读取的文本文件会出现乱码
-
字符输入转换流:InputStreamReader
-
字符输出转换流:OutputStreamWrite
-
解决思路:先获取文件的原始字符流,再将其按真实的字符集编码转为字符输入流,这样就不会乱码了
InputStream is = new FileInputStream("aaa.txt"); Reader isr = new InputStreamReader(is, "GBK"); BufferedReader br = new BufferedReader(isr); String line; while((line = br.readline)!=null){ System.out.println(line); }
OutputStream os = new FileOutputStream("aaa.txt"); Writer osw = new OutputStreamWriter(os,"GBK"); BufferedWriter bw = new BufferedWriter(osw); bw.wirte("一二三四1234");
|
5.3 IO打印流
- PrintStream、PrintWriter
- 可以实现高效、方便的打印数据出去,能实现打印杀出去就是啥出去
PrintStream ps = new PrintStream("aaa.txt"); PrintWriter ps = new PrintWriter("aaa.txt"); PrintWriter ps = new PrintWriter(new FileOutputStream("aaa.txt",true)); ps.println(97); ps.println('a');
|
- 打印流的一种应用:输出语句的重定向:把输出语句的打印位置改到某个文件中。
try(PrintStream ps = new PrintStream("aaa.txt");){ System.setOut(ps); System.out.println("一二三四"); }catch(Exception e){ e.printStackTrace(); }
|
5.4 IO数据流
- DataOutputStream(数据输出流):允许把数据和其类型一起写出去。
DataOutputStream dos = new DataOutputStream(new FileOutputStream("aaa.txt")); dos.writeInt(97); dos.writeDouble('a'); dos.writeUTF("一二三四");
|
DataInputStream dis = new DataOutputStream(new FileInputStream("aaa.txt")); int i = dis.readInt(); double d = dis.readDouble(); boolean b = dis.readBoolean(); String rs = dis.readUTF();
|
5.5 IO序列化流

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("aaa.txt")); User u = new User("admin","张三", "666888"); oos.writeObject(u);
|
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("aaa.txt")); User u = (User)ois.readObject();
private transient String code;
|
5.6 IO框架


6 特殊文件与日志技术
**特殊文件:**属性文件(properties)、xml文件
**日志技术:**程序运行的信息记录到文件中。
6.1 特殊文件——Properties
- 是一个Map集合,但是一般不会当集合用
- 核心作用:Properties是用来代表属性文件的,通过Properties可以读写属性文件的诶内容。
Properties properties = new Properties(); System.out.println(properties); properties.load(new FileReader("users.properties")); System.out.println(properties); System.out.println(properties.getProperty("赵敏")); Set<String> keys = properties.stringPropertyNames(); for(String key:keys){ String value = properties.getProperty(key); System.out.println(key + "---->" + value); } porperties.forEach((k,v)-->{System.out.println(key + "---->" + value)});
|
Properties properties = new Properties(); properties.setProperty("a","aaa"); properties.store(new FileWriter("users.properties"), "i save");
|
6.2 特殊文件——XML文件
- XML:可扩展标记语言
- XML中写”>“、”&“等会出现冲突导致报错,可用以下字符替代
< < 小于 > > 大于 & & 和号 ' ' 单引号 &quoot; " 引号
|
SAXReader saxReader = new SAXReader(); Document document = saxReader.read("aaa.xml"); Element root = document.getRootElement(); System.out.println(root.getName());
List<Element> elements = root.elements(); for(Element elememt :elements){ System.out.println(element.getName()); }
|
- 利用StringBuilder添加XML格式的数据
StringBuilder sb = new StringBuilder(); sb.append("<?xml version = \"1.0\" encoding=\"UTF-8\" ?>\r\n"); sb.append("<book>\r\n"); try( BufferedWriter bw = new BufferedWriter(new FileWriter("aaa.xml")); ){ bw.write(sb.toString()); } catch(Exception e){ e.printStackTrace(); }
|
6.3 日志技术
-
日志技术体系:
- 框架:JUL、log4j、Logback
- 日志接口:JCL、SLF4J
- logback是基于slf4j接口实现的
-
logback日志框架有以下几个模块
- logback-core
- logback-classic
- logback-access
-
实现步骤
-
导入Logback框架到项目中
-
将核心配置文件logback.xml放在src项目下面
-
创建Logger对象,调用其方法即可记录系统日志信息
public static final Logger LOGGER = LoggerFactory.getLogger("LogbackTest"); public static void main(String[] args){ try{ LOGGER.info("chu方法执行"); chu(10,0); LOGGER.info("chu方法执行成功"); }catch(Exception e){ LOGGER.error("chu出现Bug"); } } public static void chu(int a, int b){ LOGGER.debug("a"+a); LOGGER.debug("b"+b); int c == a/b; LOGGER.info("结果是" + c); }
|
- 日志级别
- trace-debug-info-warn-error
7. 多线程
7.1 概述
-
线程是一个程序内部的一个执行流程
-
多线程是从软硬件实现多条执行线程的技术
-
多线程的创建
- 方式一:继承Thread类(extends)
- 方式二:实现Runnable接口(implements)
- 优点:只是实现接口,可以继承其他类、实现其他接口,扩展性强
- 方式三:实现Callable接口(implements)
- 实现Runnable对象
- 可以在线程结束之后,用未来任务对象调用get方法获取线程执行完毕的结果
- 优点:扩展性强;可以拿到结果
- 缺点:编码复杂
Callable<String> call = new MyCallable(100); FutureTask<String> f1 = new FutureTask<>(call); new Thread(f1).start(); String rs = f1.get(); System.out.println(rs);
|
7.2 Thread常用方法
t.sleep(5000);//让t线程休眠5s
t.join();//让t线程先执行完
7.3 线程安全与线程同步
7.4 线程池
- 概念:线程池是一个可以复用线程的技术
- 问题:创建新线程的开销很大
- 结构:工作流程、任务队列
- JAVA提供线程池的接口:ExecutorService

ExecutorService pool = new ThreadPoolExecutor(3,5,8,TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
|
-
注意:
- 临时线程什么时间创建:新任务提交发现核心线程在忙,任务队列也满,并且还可以创建临时线程,此时会创建临时线程。
- 核心线程和临时线程都在忙。任务队列也满,开始拒绝任务。
-
核心线程数应该配置多少
- 计算密集型任务:核心线程数量 = CPU的核数+1;
- IO密集型任务:核心线程数量 = CPU的核数*2;
- 高并发场景中使用Executors如果不注意可能会出现风险。最好使用ThreadPoolExecutor
7.5 并发、并行
-
进程:
- 进程:正在运行的程序(软件)就是一个独立的进程。
- 线程属于进程,一个进程可以同时运行多个线程。
- 进程中的多个线程其实是并发和并行的。
-
线程的生命周期
- New
- Runnable
- Terminated
- Blocked
- Waiting
- Timed Waiting
8. 网络编程
8.1 网络编程概述
-
java.net.包下提供了网络编程的解决方案
-
通信结构:(都依赖于网络编程)
- CS架构:Client客户端/Server服务端
- 客户端需要程序员开发、用户安装
- 服务端需要程序员开发
- BS架构:Browser浏览器/Server服务端
- 客户端不需要程序员开发实现
- 服务端需要程序员开发实现
8.2 网络通信三要素
- 要素
- IP:设备在网络中的地址,是唯一标识
- 端口:应用程序在设备中唯一的标识
- 协议:连接和数据在网络中传输的规则
8.2.1 IP地址
-
ip地址
- IP:全称互联网协议地址,是分配上网设备的唯一地址
- IP地址两种形式:IPV4、IPv6
-
IP域名
- 域名→dns服务器→ip→访问服务器→返回数据在浏览器上
-
公网、内网IP
- 公网IP:是可以连接互联网的IP的地址
- 内网IP:也叫局域网IP,只能组织机构内部使用
- 192.168开头的就是内网IP
-
常用命令:
- ipconfig:查看本机IP
- ping IP地址:检查网络是否联通
InetAddress ip1 = InetAddress.getLocalHost(); System.out.println(ip1.getHostName()); System.out.println(ip1.getHostAddress()); InetAddress ip2 = InetAddress.getByName("www.baidu.com"); System.out.println(ip2.getHostName()); System.out.println(ip2.getHostAddress()); System.out.println(ip2.isReachable(6000));
|
8.2.2 端口号
- 端口:标记在计算机设备上运行的应用程序,被规定为16位的二进制(0~65535)。
- 分类:
- 周知端口(0~1023):预先被某些知名应用占用
- 注册端口(1024~49151):分配给用户进程或某些应用程序
- 动态端口(49152~65535):动态分配
- 我们自己开发的程序一般选择使用注册端口,一个设备不能出现两个程序的端口号一样
8.2.3 协议
- 协议:网络上的通信设备,事先规定的连接规则,以及传输数据的规则被称为网络通信协议
- 开放式网络互联标准:OSI网络参考模型
- OSI网络参考模型:全球网络互联标准
- TCP/IP协议:事实上的国际标准
- 程序员主要考虑应用层

- UDP:用户数据报协议
- 特点:无连接、不可靠通信
- 不事先建立连接,一般数据包含:自己的IP、程序端口、目的地IP、和数据(64KB内)
- 发送方不管对方在不在线,数据在中间丢失也不管,如果接收方收到数据也不返回确认,不可靠
- TCP:传输控制协议
- 特点:面向连接、可靠通信
- 最终目的:保证在不可靠的信道上实现可靠传输
- 主要三个步骤实现:三次我手建立连接,传输数据进行确认、四次挥手断开连接
- 三次握手:
- 四次挥手:
8.3 UDP通信
DatagramSocket socket = new DatagramSocket(7777); byte[] bytes = "xxxx".getBytes(StandardCharsets.UTF_8); DatagramPacket packet = new DatagramPacket(bytes,bytes.length , InetAddress.getLocalHost(),6666); socket.send(packet); System.out.println("done"); socket.close();
|
DatagramSocket socket = new DatagramSocket(6666);
byte[] buffer = new byte[1024*64]; DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
socket.receive(packet); int len = packet.getLength(); String rs = new String(buffer,0,len); System.out.println(rs); System.out.println(packet.getAddress().getHostAddress()); System.out.println(packet.getPort()); socket.close();
|
8.4 TCP通信
Socket socket = new Socket("127.0.0.1",8888); OutputStream os = socket.getOutputStream(); DataOutputStream dos = new DataOutputStream(os); Scanner sc= new Scanner(System.in); while (true) { System.out.println("say it"); String msg = sc.nextLine(); if("exit".equals(msg)) { dos.close(); socket.close(); break; } dos.writeUTF(msg); dos.flush();
|
ServerSocket serversocket = new ServerSocket(8888); Socket soc = serversocket.accept();
InputStream is = soc.getInputStream();
DataInputStream dis = new DataInputStream(is); while (true) { try { String rs = dis.readUTF(); System.out.println(rs); } catch (Exception e) { System.out.println(soc.getRemoteSocketAddress()+"离线了"); dis.close(); soc.close(); break;
|
9. JAVA高级
9.1 单元测试
指对最小的功能单元(方法),编写测试代码对其进行正确性测试
9.1.1 Junit单元测试框架
- 可以用来对方法进行测试,很多开发工具已经集成了Junit框架,如IDEA
- 优点:可以灵活的编写测试代码,自动生成测试报告

9.2 反射
反射就是加载类,允许以编程的方式解析类中的各种成分(成员变量,方法、构造器)