![](https://img-blog.csdnimg.cn/20201117134429299.jpg?x-oss-process=image/resize,m_fixed,h_224,w_224)
JAVA
文章平均质量分 59
JAVA、JDK等基础
游王子og
看不穿你所有的虚情假意,只触碰到你转瞬即逝的真心
展开
-
java语言入门
Java 是由 Sun 公司于 1995 年 5 月推出的 Java 面向对象程序设计语言和 Java 平台的总称。后来 Sun 公司被 Oracle (甲骨文)公司收购,Java 也随之成为 Oracle 公司的产品。Java 语言的语法与 C 语言和 C++ 语言很接近,使得大多数程序员很容易学习和使用。另一方面,Java 丢弃了 C++ 中很少使用的、很难理解的、令人迷惑的那些特性,如操作符重载、多继承、自动的强制类型转换。特别地,Java 语言不使用指针,而是引用。原创 2024-07-22 11:51:26 · 380 阅读 · 0 评论 -
java使用poi导出工具类
package com.buba.util;import com.buba.annotation.ExcelCell;import org.apache.poi.hssf.usermodel.HSSFCell;import org.apache.poi.hssf.usermodel.HSSFRow;import org.apache.poi.hssf.usermodel.HSSFSheet;import org.apache.poi.hssf.usermodel.HSSFWorkbook;.原创 2021-05-11 11:06:05 · 453 阅读 · 1 评论 -
使用poi导入excel表格
一、简介 ApachePOI项目是基于Microsoft的OLE 2复合文档格式开发纯Java文件格式端口的主项目。MicrosoftOffice文档以及使用MFC属性集序列化其文档对象的程序都使用OLE 2复合文档格式。(1)OLE 2文件的POIFSPOIFS是POI中最古老、最稳定的部分。它是我们OLE 2复合文档格式到纯Java的端口。它支持读写功能。所有用于二进制(非XML)MicrosoftOffice格式的组件最终都依赖于它。(2)Excel文档的HSSF和...原创 2020-11-17 11:46:27 · 801 阅读 · 0 评论 -
图形化用户管理(10):Swing组件一览(6)
十五、绘图 如果使用好的GUI框架,绘图应该非常简单,Swing库正是如此。对于任何绘图程序,问题在于决定绘图位置的计算通常比对绘图功能的调用要复杂的多,并且这些计算程序常常与绘图程序混在一起,所以看起来程序的接口比实际需要的要更复杂。 为了简化问题,考虑一个在屏幕上表示数据的问题,在这里,数据将由内置的Math.sin()方法提供,它可以产生数学上的正弦函数。为了使事情变得更有趣一些,也为了进一步演示Swing组件使用起来有多么简单,我们在窗体底部放置了一个滑块,用来动态控制所显示的正...原创 2020-08-07 15:23:49 · 157 阅读 · 0 评论 -
图形化用户界面(9):Swing组件一览(5)
十三、菜单 每个能够持有菜单的组件,包括JApplet、JFrame、JDialog以及它们的子类,它们都有一个setJMenuBar()方法,它接受一个JMenuBar对象(某个特定组件只能持有一个JMenuBar对象)作为参数。你先把JMenu对象添加到JMenuBar中,然后把JMenuItem添加到JMenu中。每个JMenuItem都能有一个相关联的ActionListener,用来捕获菜单项被选中时所触发的事件。 在Java的Swing中,必须在源代码中构造所有的菜单。下面是...原创 2020-08-06 16:43:24 · 216 阅读 · 0 评论 -
图形化用户界面(8):Swing组件一览(4)
十一、页签面板 JTabbedPane允许你创建“页签式的对话框”,这种对话框中沿着窗体的一边有类似文件夹的页签,当你在页签上点击时,就会向前进入到另一个不同的对话框中。package gui;import java.awt.BorderLayout;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JTabbedPane;import javax.swing.JTextField;..原创 2020-08-06 11:25:34 · 199 阅读 · 0 评论 -
图形化用户界面(7):Swing组件一览(3)
七、复选框 复选框提供了一种做出“选中”或“不选”单一选择的方式。它包含了一个小方框和一个标签。这个方框中通常是有一个“x”标记(或者其他能表明“选中”的标记)或者为空,这取决于复选框是否被选中。 通常会使用接受标签作为参数的构造器来创建JCheckBox。可以获取和设置状态,也可以获取和设置其标签,甚至可以在JCheckBox对象已经建立之后改变标签。 当JCheckBox被选中或清理选中时,将发生一个事件,你可以用与对付按钮相同的方式来捕获这个事件:使用ActionList...原创 2020-08-05 16:25:52 · 163 阅读 · 0 评论 -
图形化用户界面(6):Swing组件一览(2)
四、文本域 下面的例子演示了JTextField组件具有的其他功能:package gui;import java.awt.FlowLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JTextField;import javax..原创 2020-08-05 11:25:06 · 194 阅读 · 0 评论 -
图形化用户界面(5):Swing组件一览(1)
既然已经理解了布局管理器和事件模型,那么现在可以学习如何使用Swing组件了。本节将引导你大致浏览一下Swing组件,并介绍其最常使用的功能。每个例子都尽可能小,这样就很容易抽出所需代码,将其应用到自己的程序中。一、按钮 Swing提供了许多类型的按钮。所有的按钮,包括复选框、单选按钮,甚至菜单项,都是从AbstractButton(因为包含了菜单项,所以将其命名为“AbstractSelector”或者其他概括性的名字似乎更恰当一些)继承而来。很快你就会看到菜单项的使用,下面的例子演...原创 2020-08-04 17:02:04 · 293 阅读 · 0 评论 -
图形化用户界面(4):Swing事件模型
在Swing事件模型中,组件可以发起(触发)一个事件。每种事件的类型由不同的类表示。当事件被触发时,它将被一个或多个“监听器”接收,监听器负责处理事件。所以,事件发生的地方可以与事件处理的地方分离开。既然是以这种方式使用Swing组件,那么就只需编写组件收到事件时将被调用的代码,所以这是一个分离接口与实现的极佳例子。 所谓事件监听器,就是一个“实现特定类型的监听器接口”的类对象。所以程序员要做的就是,先创建一个监听器对象,然后把它注册到触发事件的组件。这个注册动作是通过调用触发事件的组件a...原创 2020-08-04 15:14:20 · 427 阅读 · 0 评论 -
图形化用户界面(3):控制布局
在java中,组件放置在窗体上的方式可能与你使用过的任何GUI系统都不相同。首先,它完全基于代码;没有用来控制组件布置的“资源”。第二,组件放置在窗体上的方式不是通过绝对坐标控制,而是由“布局管理器”根据组件加入的顺序决定其位置。使用不同的布局管理器,组件的大小、形状和位置将大不相同。此外,布局管理器还可以适应applet或应用程序窗口的大小,所以如果窗口的尺寸改变了,组件的大小、形状和位置也能够做相应的改变。 JApplet、JFrame、JDialog、JPanel等都可以包含和显示组...原创 2020-08-03 15:40:12 · 385 阅读 · 0 评论 -
图形化用户界面(2):Swing基础
大多数Swing应用都被构建在基础的JFrame内部,JFrame在你使用的任何操作系统中都可以创建视窗应用。视窗的标题可以像下面这样使用JFrame的构造器来设置:package gui;import javax.swing.JFrame;public class HelloSwing { public static void main(String[] args) { JFrame frame = new JFrame("Hello Swing"); frame.setD...原创 2020-08-03 11:16:52 · 285 阅读 · 0 评论 -
图形化用户界面(1):简介
java 1.0版本中的图形用户界面(graphical user interface,GUI)库,其最初的设计目标是帮助程序员编写在所有平台上都能良好表现的GUI程序。遗憾的是,这个目标没有达到。事实是java 1.0提供的“抽象窗口工具包”(Abstract Window Toolkit,AWT)在所有的系统上表现得都不太好,而且限制颇多;你只能使用四种字体,也不能访问存在于本地操作系统上的任何成熟的GUI组件。java 1.0的AWT编程模型非常笨拙,并且不是面向对象的。 java ...原创 2020-08-02 18:38:17 · 1470 阅读 · 0 评论 -
并发(23):活动对象
当你通读本章之后,可能会发现,java中的线程机制看起来非常复杂难以正确使用。另外,它好像还有点达不到预期效果的味道——尽管多个任务可以并行工作,但是你必须花很大的气力去实现防止这些任务互相干涉的技术。 如果你曾经编写过汇编语言,那么编写多线程程序就似曾相识:每个细节都很重要,你有责任处理所有事物,并且没有任何编译器检查形式的安全防护措施。 是多线程模型自身有问题吗?毕竟,它来自于过程型编程世界,并且几乎没做什么改变。可能还存在着另一种不同的并发模型,它更加适合面向对象编程。...原创 2020-08-02 14:14:13 · 396 阅读 · 0 评论 -
并发(22):性能调优(下)
三、乐观加锁 尽管Atomic对象将执行像decrementAndGet()这样的原子性操作,但是某些Atomic类还允许你执行所谓的“乐观加锁”。这意味着当你执行某项计算时,实际上没有使用互斥,但是在这项计算完成,并且你准备更新这个Atomic对象时,你需要使用一个称为compareAndSet()的方法。你将旧值和新值一起提交给这个方法,如果旧值与它在Atomic对象中发现的值不一致,那么这个操作就失败——这意味着某个其他任务已经于此操作执行期间修改了这个对象。记住,我们在正常情况下将使用互斥..原创 2020-08-01 14:07:23 · 204 阅读 · 0 评论 -
并发(21):性能调优(中)
二、免锁容器 就像在“持有对象”章节中所强调的,容器是所有编程中的基础工具,这其中自然包括并发编程。出于这个原因,想Vector和Hashtable这类早期容器具有许多synchronized方法,当然它们用于非多线程的应用程序中时,便会导致不可接受的开销。在java1.2中,新的容器类库是不同步的,并且Collections类提供了各种static的同步装饰方法,从而来同步不同类型的容器。尽管这是一种改进,因为它使你可以选择在你的容器中是否要使用同步,但是这种开销仍旧是基于synchronize..原创 2020-07-31 15:41:35 · 131 阅读 · 0 评论 -
并发(20):性能调优(上)
在java SE5的java.util.concurrent类库中存在着数量庞大的用于性能提高的类。当你细读concurrent类库时就会发现很难辨认哪些类适用于常规应用(例如BlockingQueue),而哪些类只适用于提高性能。在本节中,我们将围绕着性能调优探讨某些话题和类。一、比较各类互斥技术 既然java包括老式的synchronized关键字和java SE5中新的Lock和Atomic类,那么比较这些不同的方式,更多地理解他们各自的价值和适用范围,就显得很有意义。 ...原创 2020-06-16 16:24:46 · 206 阅读 · 0 评论 -
并发(19):仿真(下)
三、分发工作 下面的仿真示例将本章的许多概念都结合在了一起。考虑一个假想的用于汽车的机器人组装线,每辆Car都将分多个阶段构建,从构建底盘开始,紧跟着是安装发动机、车厢和轮子。package concurrency;import java.util.HashSet;import java.util.Set;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarr..原创 2020-05-29 12:43:21 · 180 阅读 · 0 评论 -
并发(18):仿真(中)
二、饭店仿真 这个仿真添加了更多的仿真组件,例如Order和Plate,从而充实了本章前面描述的Restaurant.java示例,并且它重用了枚举类型章节中的menu类。它还引入了java SE5的SynchronousQueue,这是一种没有内部容量的阻塞队列,因此每个put()都必须等待一个take(),反之亦然。这就像是你在把一个对象交给某人——没有任何桌子可以放置这个对象,因此只有在这个人伸出手,准备好接收这个对象时,你才能工作。在本例中,SynchronousQueue表示设置在用餐者..原创 2020-05-28 13:11:56 · 157 阅读 · 0 评论 -
并发(17):仿真(上)
并发最有趣也最令人兴奋的用法就是创建仿真。通过使用并发,仿真的每个构件都可以成为其自身的任务,这使得仿真更容易编程。许多视频游戏和电影的CGI动画都是仿真,前面所示的HorseRace.java和GreenhouseScheduler.java也可以被认为是仿真。一、银行出纳员仿真 这个经典的仿真可以表示任何属于下面这种类型的情况:对象随机地出现,并且要求由数量有限的服务器提供随机数量的服务时间。通过构建仿真可以确定理想的服务器数量。 在本例中,每个银行顾客要求一定数量的服务时...原创 2020-05-27 14:15:19 · 225 阅读 · 0 评论 -
并发(16):新类库中的构件(下)
六、Semaphore 正常的锁(来自concurrent.locks或内建的synchronized锁)在任何时刻都只允许一个任务访问一项资源,而计数信号量允许n个任务同时访问这个资源。你还可以将信号量看作是在向外分发使用资源的“许可证”,尽管实际上没有使用任何许可证对象。 作为一个示例,请考虑对象池的概念,它管理着数量有限的对象,当要使用对象时可以签出它们,而在用户使用完毕时,可以将它们签回。这种功能可以被封装到一个泛型类中:package concurrency;impo...原创 2020-05-26 13:03:47 · 184 阅读 · 1 评论 -
并发(15):新类库中的构件(中)
四、PriorityBlockingQueue 这是一个很基础的优先级队列,它具有可阻塞的读取操作。下面是一个示例,其中在优先级队列中的对象是按照优先级顺序从队列中出现的任务。PrioritizedTask被赋予了一个优先级数字,以此来提供这种顺序:package concurrency;import java.util.ArrayList;import java.util.List;import java.util.Queue;import java.util.Random;i..原创 2020-05-25 14:10:14 · 149 阅读 · 0 评论 -
并发(14):新类库中的构件(上)
java SE5的java.util.concurrent引入了大量设计用来解决并发问题的新类。学习使用它们将有助于你编写出更加简单而健壮的并发程序。 本节包含了各种组件具有代表性的示例,但是少数组件,即那些你不太可能用到或碰到的组件,没有包括在内。 因为这些组件设计各种问题,所以没有一种清晰的方式可以用来组织他们,因此我尝试着从最简单的示例入手,逐渐增加复杂度,从而介绍所有的示例。一、CountDownLatch 它被用来同步一个或多个任务,强制它们等待由其他任务...原创 2020-05-24 14:22:48 · 197 阅读 · 1 评论 -
并发(13):死锁
现在你理解了,一个对象可以有synchronized方法或其他形式加锁机制来防止别的任务在互斥还没有释放的时候就访问这个对象。你已经学习过,任务可以变成阻塞状态,所以就可能出现这种情况:某个任务在等待另一个任务,而后者又等待别的任务,这样一直下去,直到这个链条上的任务又在等待第一个任务释放锁。这得到了任务之间互相等待的连续循环,没有哪个线程能继续。这被称之为死锁。 如果你运行了一个程序,而它马上就死锁了,你可以立即跟踪下去。真正的问题在于,程序可能看起来工作良好,但是具有潜在的死锁危险。这...原创 2020-05-23 14:01:54 · 163 阅读 · 0 评论 -
并发(12):线程之间的协作(下)
四、生产者-消费者与队列 wait()和notifyAll()方法以一种非常低级的方式解决了任务互操作问题,即每次交互时都握手。在许多情况下,你可以瞄向更高的抽象级别,使用同步队列来解决任务协作问题,同步队列在任何时刻都只允许一个任务插入或移除元素。在java.util.concurrent.BlockingQueue接口中提供了这个队列,这个接口有大量的标准实现。你通常可以使用LinkedBlockingQueue,它是一个无界列队,还可以使用ArrayBlockQueue,它具有固定的尺寸,因..原创 2020-05-22 13:05:15 · 121 阅读 · 0 评论 -
并发(11):线程之间的协作(中)
三、生产者与消费者 请考虑这样一个饭店,它有一个厨师和一个服务员。这个服务员必须等待厨师准备好膳食。当厨师准备好时,他会通知服务员,之后服务员上菜,然后返回继续等待。这是一个任务协作的示例:厨师代表生产者,而服务员代表消费者。两个任务必须在膳食被成产和消费时进行握手,而系统必须以有序的方式关闭。下面是对这个叙述建模的代码:package concurrency;import java.util.concurrent.ExecutorService;import java.util.co..原创 2020-05-19 12:04:24 · 175 阅读 · 0 评论 -
并发(10):线程之间的协作(上)
正如你所见到的,当你使用线程来同时运行多个任务时,可以通过使用锁(互斥)来同步两个任务的行为,从而使得一个任务不会干涉另一个任务的资源。也就是说,如果两个任务在交替着步入某项共享资源(通常是内存),你可以使用互斥来使得任何时刻只有一个任务可以访问这项资源。 这个问题已经解决了,下一步学习如何使任务彼此之间可以协作,以使得多个任务可以一起工作去解决某个问题。现在的问题不是彼此之间的干涉,而是彼此之间的协调,因为在这类问题中,某些部分必须在其他部分被解决之前解决。这非常像项目规划:必须先挖房子...原创 2020-05-18 12:13:14 · 772 阅读 · 0 评论 -
并发(9):终结任务(下)
(1)被互斥所阻塞 就像在Interrupting.java中看到的,如果你尝试着在一个任务上调用其synchronized方法,而这个对象的锁已经被其他任务获得,那么调用任务将被挂起(阻塞),直至这个锁可获得。下面的示例说明了同一个互斥可以如何能被同一个任务多次获得:package concurrency;public class MultiLock { public synchronized void f1(int count) { if (count-- > 0) {..原创 2020-05-16 11:21:47 · 172 阅读 · 0 评论 -
并发(8):终结任务(上)
在前面的某些示例中,cancel()和isCanceled()方法被放到了一个所有任务都可以看到的类中。这些任务通过检查isCanceled()来确定何时终止它们自己,对于这个问题来说,这是一种合理方式。但是,在某些情况下,任务必须更加突然地终止。本节将学习到有关这种终止的各类话题和问题。 首先,让我们观察一个示例,它不仅演示了终止问题,而且还是一个资源共享的示例。一、装饰性花园 在这个仿真程序中,花园委员会希望了解每天通过多个大门进入公园的总人数。每个大门都有一个十字转门或...原创 2020-05-15 14:32:43 · 181 阅读 · 0 评论 -
并发(7):共享受限资源(下)
五、临界区 有时,你只是希望防止多个线程同时访问方法内部的部分代码而不是防止访问整个方法。通过这种方式分离出来的代码被称为临界区(critical section),它也使用synchronized关键字建立。这里,synchronized被用来指定某个对象,此对象的锁被用来对花括号内的代码进行同步控制:synchronized(syncObject) { // 一次只能一个任务完成此代码} 这也被称为同步控制块;在进入此段代码前,必须得到syncObject对象的锁。如...原创 2020-05-14 13:20:50 · 169 阅读 · 0 评论 -
并发(6):共享受限资源(中)
三、原子性与易变性 有关java线程的讨论中,一个不正确的知识是“原子操作不需要进行同步控制。”原子操作是不能被线程调度机制中断的操作;一旦操作开始,那么它一定可以在可能发生的“上下文切换”之前(切换到其他线程执行)执行完毕。依赖于原子性是很棘手且很危险的,如果你是一个并发专家,或者你得到了来自这样的专家的帮助,你才应该使用原子性来代替同步。如果你认为自己足够聪明可以应付这种玩火似的状况,那么请接受下面的测试: Goetz测试:如果你可以编写用于现代微处理器的高性能JVM,那么就有资格去...原创 2020-05-13 13:13:43 · 195 阅读 · 0 评论 -
并发(5):共享受限资源(上)
可以把单线程程序当作问题域求解的单一实体,每次只能做一件事情。因为只有一个实体,所以永远不用担心诸如“两个实体试图同时使用同一个资源”这样的问题——比如,两个人在同一个地方停车,两个人同时走过一扇门,甚至两个人同时说话。 有了并发就可以同时做多件事情了,但是,两个或多个线程彼此互相干涉的问题也就出现了。如果不防范这种冲突,就可能发生两个线程同时试图访问同一个银行账户,或向同一个打印机打印,改变同一个值等诸如此类的问题。一、不正确地访问资源 考虑下面的例子,其中一个任务产生偶数...原创 2020-05-12 15:45:51 · 250 阅读 · 0 评论 -
并发(4):基本的线程控制(下)
十、术语 正如前面各节所示,在java中,你可以选择如何实现并发编程,并且这个选择会令人困惑。这个问题通常来自于用来描述并发程序技术的术语,特别是设计线程的那些。 到目前为止,你应该看到要执行的任务与驱动它的线程之间有一个差异,这个差异在java类库中尤为明显,因为你对Thread类实际没有任何控制权(并且这种隔离在使用执行器时更加明显,因为执行器将替你处理线程的创建和管理)。你创建任务,并通过某种方式将一个线程附着到任务上,以使得这个线程可以驱动任务。 在java中,Thre...原创 2020-05-11 12:05:15 · 198 阅读 · 0 评论 -
并发(3):基本的线程控制(中)
六、优先级 线程的优先级将线程的重要性传递给了调度器。尽管CPU处理器现有线程集的顺序是不确定的,但是调度器将倾向于让优先权最高的线程先执行。然而,这并不是意味着优先权较低的线程将得不到执行(也就是说,优先权不会导致死锁)。优先级较低的线程仅仅是执行的频率较低。 在绝大多数时间里,所有线程都应该以默认的优先级运行。试图操纵线程优先级通常是一种错误。 下面是一个演示优先级等级的示例,你可以用getPriority()来读取现有线程的优先级,并且在任何时刻都可以通过setPrior...原创 2020-05-10 14:18:07 · 175 阅读 · 0 评论 -
并发(2):基本的线程控制(上)
并发编程使我们可以将程序划分为多个分离的、独立运行的任务。通过使用多线程机制,这些独立任务(也被称为子任务)中的每一个都将由执行线程来驱动。一个线程就是在进程中的一个单一的顺序控制流,因此,单个进程可以拥有多个并发执行的任务,但是你的程序使得每个任务都好像有其自己的CPU一样。其底层机制是切分CPU时间,但通常你不需要考虑它。 线程模型为编程带来了便利,它简化了在单一程序中同时交织在一起的多个操作的处理。在使用线程时,CPU将轮流给每个任务分配其占用时间。每个任务都觉得自己在一直占用CPU...原创 2020-05-09 15:09:21 · 135 阅读 · 0 评论 -
并发(1):并发的多面性
到目前为止,你学到的都是有关顺序编程的知识。即程序中所有事物在任意时刻都只能执行一个步骤。 编程问题中相当大的一部分都可以通过使用顺序编程来解决。然而,对于某些问题,如果能够并行的执行程序中的多个部分,则会变得非常方便甚至非常必要,因为这些部分要么看起来在并发地执行,要么在多处理器环境下可以同时执行。 并行编程可以使程序执行速度得到极大提高,或者为设计某些类型的程序提供...原创 2020-05-08 13:54:08 · 263 阅读 · 0 评论 -
注解(4):基于注解的单元测试
一、简介 单元测试是软件开发中必不可少的一环,但是在平常开发中往往因为项目周期紧,工作量大而被选择忽略,这样往往导致软件问题层出不穷。线上出现的不少问题其实在有单元测试的情况下就可以及时发现和处理,因此培养自己在日常开发中写单元测试的能力是很有必要的。无论是对自己的编码能力的提高,还是项目质量的提升,都是大有好处,接下来将介绍 Java 单元测试框架 JUnit 5 的基础认识和使用来编...原创 2020-05-07 16:39:22 · 866 阅读 · 0 评论 -
注解(3):插件化注解处理API(Pluggable Annotation Processing API)
一、基本用法 件化注解处理(Pluggable Annotation Processing)APIJSR 269提供一套标准API来处理AnnotationsJSR 175,实际上JSR 269不仅仅用来处理Annotation,我觉得更强大的功能是它建立了Java 语言本身的一个模型,它把method、package、constructor、type、variable、enum、ann...原创 2020-05-07 15:11:54 · 517 阅读 · 0 评论 -
注解(2):编写注解处理器
如果没有用来读取注解的工具,那注解也不会比注释更有用。使用注解过程中,很重要的一个部分就是创建与使用注解处理器。java SE5扩展了反射机制的API,以帮助程序员构造这类工具。同时,它还提供了一个外部工具apt帮助程序员解析带有注解的java源代码。 下面是一个非常简单的注解处理器,我们将用它来读取PasswordUtils类,并使用反射机制查找@UseCase标记。我们为其提...原创 2020-05-06 14:06:02 · 286 阅读 · 0 评论 -
注解(1):基本语法
注解(也被称为元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据。 注解在一定程度上是把元数据与源代码文件结合在一起,而不是保存在外部文档中这一大的趋势之下所催生的。同时,注解也是对来自像C#之类的其他语言对java造成的语言特性压力所做出的一种回应。 注解是众多引入到java SE5中的重要的语言变化之一。它们可以提供...原创 2020-05-05 15:21:48 · 324 阅读 · 0 评论