黑马程序员-JAVA.net-网络工具类粗解

2024-01-02 19:08

本文主要是介绍黑马程序员-JAVA.net-网络工具类粗解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-


Java自1.0就已集成网络操作的工具,提供了从基于流的Java.net包以实现网络访问和操作,而Java1.4又假如了nio包,利用异步和面向缓冲的新方式实现了更高效的网络操作工具类,并以此重写了部分io包中的内容。

Java.net

java.net 包可以大致分为两个部分:

  • 低级 API,用于处理以下抽象:
    • 地址,也就是网络标识符,如 IP 地址。
    • 套接字,也就是基本双向数据通信机制。
    • 接口,用于描述网络接口。
  • 高级 API,用于处理以下抽象:
    • URI,表示统一资源标识符。
    • URL,表示统一资源定位符。
    • 连接,表示到 URL 所指向资源的连接。

地址

InetAddress 类是表示 IP(Internet 协议)地址的抽象。它拥有两个子类:
- 用于 IPv4 地址的 Inet4Address。
- 用于 IPv6 地址的 Inet6Address。
IP 地址是 IP 使用的4个byte(IPv4)或者16个byte(IPv6);对于Hostname,将通过主机名解析服务(通常是DNS)将他解析为IP地址。

ipv6

并非所有系统和网络环境都支持 IPv6 协议,在 IPv6 不可用或被显式禁用的情况下,在此情况下,大多数方法在使用 Inet6Address 调用时都将抛出异常。

简单的创建InetAddress 的例子
try {InetAddress ip = null;//localhostip = Inet4Address.getLocalHost();sp(ip);//xxxx-xxxx/192.168.1.100 for example//loopbackip= Inet4Address.getLoopbackAddress();sp(ip);//localhost/127.0.0.1 //Indicate a ip & hostname without NSip=Inet4Address.getByAddress("Its.A.Fake.Domian", new byte[]{(byte) 0xfe,(byte) 0xfe,(byte) 0xfe,(byte) 0xfe});sp(ip);//Its.A.Fake.Domian/254.254.254.254//Indicate a ip with 4bytes for ipv4ip=Inet4Address.getByAddress(new byte[]{(byte) 0xfe,(byte) 0xfe,(byte) 0xfe,(byte) 0xfe});sp(ip);///254.254.254.254//Indicate a ip for hostname using NSip=Inet4Address.getByName("www.oracle.com");sp(ip);//www.oracle.com/184.50.90.127} catch (UnknownHostException e) {e.printStackTrace();}

套接字

套接字是实际操作传输层的Java工具对象,基于UDP和TCP的传输都可以通过构建套接字来完成。

端口

端口是TCP和UDP协议中对同一IP地址不同应用对象的区分手段,TCP与UDP的端口是互不影响的。

UDP与DatagramSocket

UDP:User Datagram Protocol是一种面向无连接,基于数据包的传输层协议,一个UDP数据包最大为65535bytes。但是UDP不含任何传输保证,数据的有效性必须由应用自行处理,但相对于TCP,它的连接开销小,相对速度快,很多协议也是基于UDP的,比如很重要的DNS(UDP53)协议,DHCP(UDP67/68)协议;另外很多协议同时支持TCP以及UDP以实现更好的数据交换。

DatagramSocket是Java中处理UDP点对点传输的网络端点对象。通过传输DatagramPacket网络包实现UDP协议的传输。将DatagramPacket目标指定为广播地址可以实现域内网络多播。

DatagramSocket的构造方法允许指定端口,当绑定端口失败时会抛出SocketException;若不指定,将由JVM随机安排一个可用的端口。
由于端口属于系统资源,必须保证端口在使用完后通过close()方法释放。

MulticastSocket

UDP的组播,多播组通过 D 类 IP 地址和标准 UDP 端口号指定,通过joinGroup(group)加入组,将消息发送到多播组时,该主机和端口的所有预定接收者都将接收到消息,多个 MulticastSocket 可以同时预定多播组和端口,并且都会接收到组数据报。

UDP的简单例子

一个简单的控制台通过本地环回的UDP信息收发

        final int port = 36314;try {UdpReciver serv = new UdpReciver(port);StringUdpSender cli=new StringUdpSender(port);new Thread(serv).start();new Thread(cli).start();ts(10000);serv.stop();} catch (IOException e) {e.printStackTrace();}
class StringUdpSender implements Runnable {private DatagramSocket soc;private final String exitFlag;private final int port;public StringUdpSender(int port,String exitFlag) throws SocketException {super();this.exitFlag = exitFlag;soc=new DatagramSocket();this.port=port;}public StringUdpSender(int port) throws SocketException {this(port,"exit");}@Overridepublic void run() {String msg=null;BufferedReader br= new BufferedReader(new  InputStreamReader(System.in));DatagramPacket dp=null;while(true){try {msg=br.readLine();if(!exitFlag.equals(msg)){dp=new DatagramPacket(msg.getBytes(), msg.getBytes().length, InetAddress.getByName("localhost"), port);soc.send(dp);}else{break;}} catch (IOException e) {e.printStackTrace();}}if (soc != null && !soc.isClosed()) {soc.close();}}}class UdpReciver implements Runnable {private DatagramSocket soc;private volatile boolean runFlag = false;public UdpReciver(int port) throws SocketException {super();this.soc = new DatagramSocket(port);}public void stop() {this.setRunFlag(false);}public boolean isRunning() {return runFlag;}private synchronized void setRunFlag(boolean runFlag) {this.runFlag = runFlag;}@Overridepublic void run() {this.setRunFlag(true);DatagramPacket dp = new DatagramPacket(new byte[1024], 1024);while (runFlag) {try {this.soc.receive(dp);} catch (IOException e) {e.printStackTrace();}sp(dp.getAddress());sp(new String(dp.getData(),0,dp.getLength()));}if (soc != null && !soc.isClosed()) {soc.close();sp("Server stop");}}@Overrideprotected void finalize() throws Throwable {super.finalize();if (soc != null && !soc.isClosed()) {soc.close();}}
}
TCP

TCP(Transfer Control Protocol)是面向连接的,相对可靠的数据传输协议,TCP的双方必须经过3次握手来达成一个连接,有了连接之后才能开始传输数据,TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和,一旦有问题将请求重发,包丢失也将请求重发,而重复的包将丢弃。这样TCP就达成了一个可靠的数据传送。
TCP的连接时有状态的,双方通过协议信号更新彼此的状态,常见的服务端LISTEN表示监听中,任一方ESTABLISHED 表示连接已建立等。

Socket

Socket是Java中TCP端点的抽象,套接字的实际工作由 SocketImpl 类的实例执行。
客户端可以通过构造一个包含服务器IP和端口的Socket尝试打开TCP连接。
打开连接之后,可以通过getInputStream和getOutputStream与对端通信。

ServerSocket

ServerSocket是Java中TCP服务端的抽象,绑定一个端口即可开始服务。服务器套接字的实际工作由 SocketImpl 类的实例执行。
ServerSocket通过accept() 阻塞方法获得客户端的连接,然后可以操作这个连接来处理交互。

TCP服务器和客户端的简单例子

这个例子实现了简单的TCP服务器和客户端,服务器对客户端送来的String简单的+上”response”返回客户端,服务端实现了简单的异步消息和连接统计。


public class TcpDemo {public static void main(String[] args) {final int serverPort = 23333;InetAddress serverAddr = null;try {serverAddr = InetAddress.getLocalHost();} catch (UnknownHostException e1) {e1.printStackTrace();}//start Servertry {new Thread(new TcpServer(serverPort)).start();} catch (IOException e1) {e1.printStackTrace();}//start ClientSocket s = null;//5 thread client
//      for (int i = 0; i < 5; i++) {
//          try {
//              s = new Socket(serverAddr, serverPort);
//          } catch (IOException e) {
//              e.printStackTrace();
//          }
//          new Thread(new TcpClient(s)).start();
//      }//about 400 thread clientwhile(true){ts(10);try {s = new Socket(serverAddr, serverPort);} catch (IOException e) {e.printStackTrace();}new Thread(new TcpClient(s)).start();}}}class TcpClient implements Runnable {//end connection key wordpublic static final String ENDCONN="##$$$$##";Socket socket;public TcpClient(Socket socket) {super();this.socket = socket;}@Overridepublic void run() {
//      sp(socket+" Client");//client request//emulate chatRandom r=new Random();int times=r.nextInt(20)+5;PrintWriter pw=null;BufferedReader bfr=null;try {pw = new PrintWriter(socket.getOutputStream());bfr=new BufferedReader(new InputStreamReader(socket.getInputStream()));} catch (IOException e1) {e1.printStackTrace();}for (int i = 0; i < times; i++) {String msg = "hello from"+socket.getLocalPort()+"##"+i;pw.println(msg);pw.flush();try {msg=bfr.readLine();} catch (IOException e) {e.printStackTrace();}
//          sp(msg);ts(300);}pw.println(TcpClient.ENDCONN);pw.flush();
//      if(socket!=null && !socket.isClosed()){
//          try {
//              socket.close();
//          } catch (IOException e) {
//              e.printStackTrace();
//          }
//      }}}class TcpServer implements Runnable {private ServerSocket s;private ExecutorService exes;private final BlockingQueue<Socket> connects;private volatile ConcurrentHashMap<String, Future<String>> results;public TcpServer(int port) throws IOException {super();this.s = new ServerSocket(port);this.exes = Executors.newCachedThreadPool();this.connects = new SynchronousQueue<Socket>();this.results = new ConcurrentHashMap<String, Future<String>>();}@Overridepublic void run() {// Dispatcher threadnew Thread(new Runnable() {@Overridepublic void run() {while (true) {try {Socket s = connects.take();String stamp = s.toString() + Instant.now().toString();Future<String> result = exes.submit(new RequestHandler(s));results.put(stamp, result);} catch (InterruptedException e) {e.printStackTrace();}}}}).start();// Result collector threadnew Thread(new Runnable() {@Overridepublic void run() {while (true) {ts(1000);List<String> remove=new ArrayList<String>();results.forEach((String stamp,Future<String> result) -> {if(result.isDone()){try {
//                              sp(result.get());remove.add(stamp);} catch (Exception e) {e.printStackTrace();}}else if(result.isCancelled()){
//                          sp(stamp+" is Cancelled");remove.add(stamp);}});for (String string : remove) {results.remove(string);}sp("Missions : "+results.size());}}}).start();//Serv to Clientwhile (true) {try {final Socket socket = s.accept();try {this.connects.put(socket);} catch (InterruptedException e) {e.printStackTrace();}} catch (IOException e) {e.printStackTrace();}}}}class RequestHandler implements Callable<String> {private Socket socket;public RequestHandler(Socket conn) {super();this.socket = conn;}@Overridepublic String call() throws Exception {//server BusinessPrintWriter pw=null;BufferedReader bfr=null;String msg=null;try {pw = new PrintWriter(socket.getOutputStream());bfr=new BufferedReader(new InputStreamReader(socket.getInputStream()));} catch (IOException e1) {e1.printStackTrace();}while(true){msg=bfr.readLine();if(TcpClient.ENDCONN.equals(msg)){
//              sp(this+" recieved ENDCONN");break;}
//          sp(msg);pw.println(msg+" : responsed");pw.flush();}socket.close();return "done :"+socket;}}

网络接口

NetworkInterface 实际指的是网络设备,包括硬件和软件模拟的,比如本地网络环回(lo)就是一个操作系统虚拟的网络设备。
NetworkInterface类提供Java访问本地NetworkInterface的工具,通过它,可以查询比如MAC地址,接口是否物理/虚拟,当前传输MTU值等等有价值的硬件信息,它还有一个很便捷的方法NetworkInterface getByInetAddress(InetAddress addr):可以查询绑定了指定IP地址的网络接口。

高级 API

URI

Uniform Resource Identifier 统一资源标识符,是表示一个网络中资源的标识字符串,这种标识指定了某种协议以便使用者通过合适的方式使用。
URI由URL(地址)和URN(名称)组成,常见的URI有不透明URI和分层URI
比如mailto:java-net@java.sun.com urn:isbn:096139210x 就是不透明URI,其特点是方案定义部分不以’/’开始,其结构可以表示为:[scheme:]scheme-specific-part[#fragment]
而更常见的是分层URI,http://java.sun.com/j2se/1.3/ docs/guide/collections/designfaq.html#28 ../../../demo/jfc/SwingSet2/src/SwingSet2.java 等都是分层URI,分层 URI 还要按照下面的语法进行进一步的解析:[scheme:][//authority][path][?query][#fragment]

Java.net中的URI类提供了构造和解析URI的方便工具,可以通过字符串解析URI的各个部分,也可以通过已有URI构建新的URI。最后,可以把从URI提取URL来使用,这也是最常用的。

URL

Uniform Resource Location 统一资源定位符 ,它是指向互联网“资源”的指针。URL是URI的定位部分,他们之间可以用toURI() 和toURL() 方法相互转换 。
URL 可选择指定一个“端口”,它是用于建立到远程主机 TCP 连接的端口号。如果未指定该端口号,则使用协议默认的端口。例如,http 协议的默认端口为 80。还可以指定一个备用端口,用.au:端口号

Java.net中的URL类除了像URI一样可以解析和构造(解析和构造也可以使用URLDecoder和URLEncoder)以外,特别的,它提供了一个极其方便的方法 openConnection()返回一个URLConnection对象,这个方法通过反射查询当前jre支持的协议,如果支持就打开一个协议连接,然后就可以直接操作了。

URLConnection

这里是一个打开HttpURLConnection的例子:

            URL url=new URL("http://www.java.com");URLConnection conn=url.openConnection();BufferedReader bfr=new BufferedReader(new InputStreamReader(conn.getInputStream()));String str;while((str=bfr.readLine())!=null){sp(str);}
协议处理程序

Java中不仅可以直接使用系统的协议处理程序打开连接,也可以自定义协议处理程序,只需要继承URLStreamHandler抽象类即可。

Java.nio 中的网络相关

@Since Java 1.4
Java1.4中加入了新的IO体系(JSR 51),包括面向缓冲区的各种Buffer对象,双向连接的Channel,Selector模式的多路复用。
在Java1.7中,nio又得到了补充(JSR 203),包括更多的文件系统操作API(包括可插拔的自定义的文件系统), 还提供了对socket和文件的异步(Async) I/O操作。

用Async方法实现异步网络服务

下面是一个基于异步非阻塞模式的服务器简单例子,双方仅仅是简单的进行几十次字符串传递即关闭连接。


import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.*;import static cc.sisel.util.Quic.*;/*** @author lz**/
public class AsyncTcpDemo {public static void main(String[] args) throws IOException,InterruptedException, ExecutionException {timeMark();InetSocketAddress servAddr = new InetSocketAddress("localhost", 22333);// start servernew Thread(new Runnable() {@Overridepublic void run() {new AsyncServer(servAddr.getPort(), 100).start();// blocking server main thread to keep async alivewhile (true) {try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {e.printStackTrace();}}}}).start();// wait server initts(300);Random r = new Random();// 5000 clientsfor (int i = 0; i < 5000; i++) {ts(10);new Thread(new AsyncClient(servAddr, r.nextInt(50) + 10)).start();}sp("ALL DONE");}}class AsyncServer {private AsynchronousServerSocketChannel servsc;private final int port, backlog;private boolean started;public AsyncServer(int port, int backlog) {super();this.port = port;this.backlog = backlog;init();}public void start() {// start by accept a connection channelservsc.accept(null, new AcceptCompletionHandler());this.started = true;}private void init() {// build async groupAsynchronousChannelGroup asyncGroup = null;try {// async thread poolasyncGroup = AsynchronousChannelGroup.withCachedThreadPool(Executors.newCachedThreadPool(), 10);} catch (IOException e) {e.printStackTrace();}// open serversockettry {this.servsc = AsynchronousServerSocketChannel.open(asyncGroup);} catch (IOException e) {e.printStackTrace();}// config addr resuse & tcp recieve buffertry {this.servsc.setOption(StandardSocketOptions.SO_REUSEADDR, true);this.servsc.setOption(StandardSocketOptions.SO_RCVBUF, 16 * 1024);} catch (IOException e) {e.printStackTrace();}// bind to port ;ip= 0.0.0.0 for everyonetry {this.servsc.bind(new InetSocketAddress("0.0.0.0", this.port),this.backlog);} catch (IOException e) {e.printStackTrace();}}public void pendingAccept() {// after accepted channel reaccept cycliclyif (this.started && this.servsc.isOpen()) {servsc.accept(null, new AcceptCompletionHandler());} else {throw new IllegalStateException("Controller has been closed");}}// accept complete event handlerclass AcceptCompletionHandler implementsCompletionHandler<AsynchronousSocketChannel, Object> {final ByteBuffer buffer = ByteBuffer.allocate(1024);@Overridepublic void completed(AsynchronousSocketChannel channel,Object attachment) {new ASession(channel, AsyncServer.this).start();}@Overridepublic void failed(Throwable exc, Object attachment) {System.out.println("failed: " + exc);pendingAccept();}}}/*** server session handle it's read & write* * @author lz**/
class ASession {private AsynchronousSocketChannel channel;private AsyncServer server;private final ByteBuffer buffer = ByteBuffer.allocate(1024);private WriteCompletionHandler writeh;private ReadCompletionHandler readh;public ASession(AsynchronousSocketChannel channel, AsyncServer server) {this.channel = channel;this.writeh = new WriteCompletionHandler();this.readh = new ReadCompletionHandler();this.server = server;}public void start() {channel.read(buffer, null, readh);}class WriteCompletionHandler implements CompletionHandler<Integer, Object> {@Overridepublic void completed(Integer result, Object attachment) {if (channel.isOpen()) {buffer.clear();channel.read(buffer, 20, TimeUnit.SECONDS, null, readh);}}@Overridepublic void failed(Throwable exc, Object attachment) {sp("########################## WRITE FAIL IN SERVER");exc.printStackTrace();}}class ReadCompletionHandler implements CompletionHandler<Integer, Object> {@Overridepublic void completed(Integer result, Object attachment) {buffer.flip();String msg = readBuffer(buffer);// sp("server recieved:" + msg);buffer.clear();// if ENDCODE then close session and pending server nextif (AsyncClient.ENDCODE.equals(msg)) {if (channel.isOpen()) {try {channel.close();} catch (IOException e) {e.printStackTrace();}}server.pendingAccept();} else {// write responseif (channel != null && channel.isOpen()) {channel.write(ByteBuffer.wrap((msg + " responsed.").getBytes()),10, TimeUnit.SECONDS, null, writeh);}}}@Overridepublic void failed(Throwable exc, Object attachment) {sp("########################## READ FAIL IN SERVER");exc.printStackTrace();}}
}/*** client emualtor send simple message & recieve* * @author lz**/
class AsyncClient implements Runnable {public static final String ENDCODE = "&#$$#&$$";private final InetSocketAddress serverAddr;private int chatCount;private AsynchronousSocketChannel client = null;private final ByteBuffer buffer = ByteBuffer.allocate(1024);// event handlesprivate ConnectCompletionHandler connecth;private WriteCompletionHandler writeh;private ReadCompletionHandler readh;private NullCompletionHandler endh;public AsyncClient(InetSocketAddress serverAddr, int chatCount) {super();this.serverAddr = serverAddr;this.chatCount = chatCount < 1 ? 1 : chatCount;this.connecth = new ConnectCompletionHandler();this.writeh = new WriteCompletionHandler();this.readh = new ReadCompletionHandler();this.endh = new NullCompletionHandler();}@Overridepublic void run() {try {client = AsynchronousSocketChannel.open();} catch (IOException e) {e.printStackTrace();}// launch connif (client != null && client.isOpen()) {client.connect(serverAddr, null, connecth);}}class ConnectCompletionHandler implements CompletionHandler<Void, Object> {@Overridepublic void completed(Void result, Object attachment) {buffer.clear();if (chatCount > 0) {ts(300);if (client.isOpen()) {client.write(ByteBuffer.wrap(("message:" + chatCount).getBytes()), 10, TimeUnit.SECONDS, null, writeh);chatCount--;}} else {if (client.isOpen()) {client.write(ByteBuffer.wrap(ENDCODE.getBytes()), 10,TimeUnit.SECONDS, null, endh);}}}@Overridepublic void failed(Throwable exc, Object attachment) {sp("########################## CONNECT FAIL IN CLIENT");ts(300);client.connect(serverAddr, null, connecth);exc.printStackTrace();}}class WriteCompletionHandler implements CompletionHandler<Integer, Object> {@Overridepublic void completed(Integer result, Object attachment) {if (client.isOpen()) {buffer.clear();client.read(buffer, 20, TimeUnit.SECONDS, null, readh);}}@Overridepublic void failed(Throwable exc, Object attachment) {sp("########################## WRITE FAIL IN CLIENT");exc.printStackTrace();}}class ReadCompletionHandler implements CompletionHandler<Integer, Object> {@Overridepublic void completed(Integer result, Object attachment) {if (client.isOpen()) {buffer.flip();String msg = readBuffer(buffer);// sp("client recieved :" + msg);buffer.clear();if (chatCount > 0) {// ts(300);client.write(ByteBuffer.wrap(("message:" + chatCount).getBytes()), 10, TimeUnit.SECONDS, null, writeh);chatCount--;} else {client.write(ByteBuffer.wrap(ENDCODE.getBytes()), 10,TimeUnit.SECONDS, null, endh);}}}@Overridepublic void failed(Throwable exc, Object attachment) {sp("########################## READ FAIL IN CLIENT");exc.printStackTrace();}}
}class NullCompletionHandler implements CompletionHandler<Integer, Object> {@Overridepublic void completed(Integer result, Object attachment) {//just do nothing}@Overridepublic void failed(Throwable exc, Object attachment) {//just do nothing}}

附:
- sp和ts方法,偷懒用:

/*** 简单的在控制台输出 对于非数组类型,输出.toString() 对于数组类型,输出:类型[内容] 不递归* * @param o*            被打印的对象*/public static void sp(Object o) {if (o == null) {System.out.println("null");return;}if (o.getClass().isArray()) {StringBuilder sb = new StringBuilder();int len = Array.getLength(o);sb.append(o.getClass().getComponentType().getSimpleName());if (len == 0) {sb.append("[]");System.out.println(sb.toString());return;}sb.append('[');for (int i = 0; i < len; i++) {if (i != 0) {sb.append(':');}sb.append(Array.get(o, i));}sb.append(']');System.out.println(sb.toString());} else {System.out.println(o);}}/*** 简单的换行 调用sp("");*/public static void sp() {sp("");}/*** !!仅用于test 或者 demo 简单的包装了Thread.sleep(millis); 并catch* (InterruptedException e)不作任何处理* * @param millis 毫秒数*            @see java.lang.Thread#sleep(long millis)*/public static void ts(long millis) {if(millis<0){return;}try {Thread.sleep(millis);} catch (InterruptedException e) {e.printStackTrace();}}

这篇关于黑马程序员-JAVA.net-网络工具类粗解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/563387

相关文章

SpringBoot中四种AOP实战应用场景及代码实现

《SpringBoot中四种AOP实战应用场景及代码实现》面向切面编程(AOP)是Spring框架的核心功能之一,它通过预编译和运行期动态代理实现程序功能的统一维护,在SpringBoot应用中,AO... 目录引言场景一:日志记录与性能监控业务需求实现方案使用示例扩展:MDC实现请求跟踪场景二:权限控制与

在.NET平台使用C#为PDF添加各种类型的表单域的方法

《在.NET平台使用C#为PDF添加各种类型的表单域的方法》在日常办公系统开发中,涉及PDF处理相关的开发时,生成可填写的PDF表单是一种常见需求,与静态PDF不同,带有**表单域的文档支持用户直接在... 目录引言使用 PdfTextBoxField 添加文本输入域使用 PdfComboBoxField

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

Java注解之超越Javadoc的元数据利器详解

《Java注解之超越Javadoc的元数据利器详解》本文将深入探讨Java注解的定义、类型、内置注解、自定义注解、保留策略、实际应用场景及最佳实践,无论是初学者还是资深开发者,都能通过本文了解如何利用... 目录什么是注解?注解的类型内置注编程解自定义注解注解的保留策略实际用例最佳实践总结在 Java 编程

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推