注解
注解简介
Java 5 版本之后可以在源代码中嵌入一些补充信息,这种补充信息称为注解(Annotation),是 Java 平台中非常重要的一部分。注解都是 @ 符号开头的,例如我们在学习方法重写时使用过的 @Override 注解。同 Class 和 Interface 一样,注解也属于一种类型。
注解并不能改变程序的运行结果,也不会影响程序运行的性能。有些注解可以在编译时给用户提示或警告,有的注解可以在运行时读写字节码文件信息。
@Override注解
Java 中 @Override 注解是用来指定方法重写的,只能修饰方法并且只能用于方法重写,不能修饰其它的元素。它可以强制一个子类必须重写父类方法或者实现接口的方法。
@Override 的作用是告诉编译器检查这个方法,保证父类要包含一个被该方法重写的方法,否则就会编译出错。这样可以帮助程序员避免一些低级错误。
@Deprecated注解
Java 中 @Deprecated 可以用来注解类、接口、成员方法和成员变量等,用于表示某个元素(类、方法等)已过时。当其他程序使用已过时的元素时,编译器将会给出警告。
@Deprecated 的作用与文档注释中的 @deprecated 标记的作用基本相同,但它们的用法不同,前者是 Java 5 才支持的注解,无须放在文档注释语法(/** ... */部分)中,而是直接用于修饰程序中的程序单元,如方法、类和接口等。
@SuppressWarnings:抑制编译器警告
Java 中的 @SuppressWarnings 注解指示被该注解修饰的程序元素(以及该程序元素中的所有子元素)取消显示指定的编译器警告,且会一直作用于该程序元素的所有子元素。例如,使用 @SuppressWarnings 修饰某个类取消显示某个编译器警告,同时又修饰该类里的某个方法取消显示另一个编译器警告,那么该方法将会同时取消显示这两个编译器警告。
@SuppressWarnings 注解主要用在取消一些编译器产生的警告对代码左侧行列的遮挡,有时候这样会挡住我们断点调试时打的断点。
如果你确认程序中的警告没有问题,可以不用理会。通常情况下,如果程序中使用没有泛型限制的集合将会引起编译器警告,为了避免这种编译器警告,可以使用 @SuppressWarnings 注解消除这些警告。
注解的使用有以下三种: 抑制单类型的警告:@SuppressWarnings("unchecked") 抑制多类型的警告:@SuppressWarnings("unchecked","rawtypes") 抑制所有类型的警告:@SuppressWarnings("unchecked")
@SafeVarargs注解
public class HelloWorld {
public static void main(String[] args) {
// 传递可变参数,参数是泛型集合
display(10, 20, 30);
// 传递可变参数,参数是非泛型集合
display("10", 20, 30); // 会有编译警告
}
public static <T> void display(T... array) {
for (T arg : array) {
System.out.println(arg.getClass().getName() + ":" + arg);
}
}
}
@FunctionalInterface注解
在学习 Lambda 表达式时,我们提到如果接口中只有一个抽象方法(可以包含多个默认方法或多个 static 方法),那么该接口就是函数式接口。@FunctionalInterface 就是用来指定某个接口必须是函数式接口,所以 @FunInterface 只能修饰接口,不能修饰其它程序元素。
Java 自定义注解
声明自定义注解使用 @interface 关键字(interface 关键字前加 @ 符号)实现。定义注解与定义接口非常像,如下代码可定义一个简单形式的注解类型。
定义注解和定义类相似,注解前面的访问修饰符和类一样有两种,分别是公有访问权限(public)和默认访问权限(默认不写)。一个源程序文件中可以声明多个注解,但只能有一个是公有访问权限的注解。且源程序文件命名和公有访问权限的注解名一致。
实例
public class Demo08 {
public static void main(String[] args) {
// 获取UN类的class对象
Class cls = UN.class;
// 获取类上的注解
Username username = (Username) cls.getDeclaredAnnotation(Username.class);
System.out.println(username.name());
System.out.println(username.num());
System.out.println("********************************************");
// 获取方法上的注解
// 获取当前类的所有方法
try {
Method pwd = cls.getDeclaredMethod("pwd");
Pwd annotation = pwd.getAnnotation(Pwd.class);
System.out.println(annotation.password());
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
System.out.println("********************************************");
// 获取变量上的注解
// 获取变量(属性)
try {
Field message = cls.getDeclaredField("message");
// 获取当前属性上的注解
Val annotation = message.getAnnotation(Val.class);
System.out.println(annotation.value());
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
@Username(name = "大锤", num = 100)
class UN{
@Val("变量")
public String message;
@Pwd(password = "123456")
public void pwd(){
System.out.println("这是自定义方法");
}
}
向量(Vector)
向量(Vector)类和传统数组非常相似,但是Vector的大小能根据需要动态的变化。和数组一样,Vector对象的元素也能通过索引访问。使用Vector类最主要的好处就是在创建对象的时候不必给对象指定大小,它的大小会根据需要动态的变化。
Vector 类实现了一个动态数组。和 ArrayList 很相似,但是两者是不同的: 1、Vector 是同步访问的。 2、Vector 包含了许多传统的方法,这些方法不属于集合框架。
Vector 主要用在事先不知道数组的大小,或者只是需要一个可以改变大小的数组的情况。Vector 类支持 4 种构造方法。第一种构造方法创建一个默认的向量,默认大小为 10:
import java.util.Date;
import java.util.Vector;
public class Demo01 {
public static void main(String[] args) {
// 创建默认大小的向量(10)
Vector v = new Vector();
// 在此向量的指定位置插入指定的元素。
v.add(0, "张三");
// 插入元素
v.add("大锤");
// 将指定的组件添加到此向量的末尾,将其大小增加 1。
v.addElement(new Date());
System.out.println(v);
// 返回此向量的当前容量。
System.out.println(v.capacity());
// 从此向量中移除所有元素。
// v.clear();
// 如果此向量包含指定的元素,则返回 true。
System.out.println(v.contains("大锤"));
// 返回向量中指定位置的元素
System.out.println(v.get(2));
// 返回此向量中的组件数
System.out.println(v.size());
}
}
栈(Stack)
栈(Stack)实现了一个后进先出(LIFO)的数据结构。可以把栈理解为对象的垂直分布的栈,当你添加一个新元素时,就将新元素放在其他元素的顶部。
栈是Vector的一个子类,它实现了一个标准的后进先出的栈。
堆栈只定义了默认构造函数,用来创建一个空栈。 堆栈除了包括由Vector定义的所有方法,也定义了自己的一些方法。
import java.util.List;
import java.util.Stack;
public class Demo01 {
public static void main(String[] args) {
// 创建栈对象,栈的特点:后进先出的原则
Stack s = new Stack();
// 往栈当中存放数据,压栈
s.push("大锤");
s.push("张三");
s.push("李四");
s.push("王五");
// 查看堆栈顶部的对象,但不从堆栈中移除它。
System.out.println("查看堆栈顶部的对象,但不从堆栈中移除它。" + s.peek());
// 获取栈的大小
System.out.println(s.size());
System.out.println(s.pop());
// 获取栈的大小
System.out.println(s.size());
System.out.println(s.pop());
// 获取栈的大小
System.out.println(s.size());
System.out.println(s.pop());
// 获取栈的大小
System.out.println(s.size());
System.out.println(s.pop());
// 获取栈的大小
System.out.println(s.size());
// 判断栈是否为空
System.out.println(s.empty());
}
}
哈希表(Hashtable)
Hashtable类提供了一种在用户定义键结构的基础上来组织数据的手段。例如,在地址列表的哈希表中,你可以根据邮政编码作为键来存储和排序数据,而不是通过人名。哈希表键的具体含义完全取决于哈希表的使用情景和它包含的数据。
Hashtable是原始的java.util的一部分, 是一个Dictionary具体的实现 。然而,Java 2 重构的Hashtable实现了Map接口,因此,Hashtable现在集成到了集合框架中。它和HashMap类很相似,但是它支持同步。像HashMap一样,Hashtable在哈希表中存储键/值对。当使用一个哈希表,要指定用作键的对象,以及要链接到该键的值。然后,该键经过哈希处理,所得到的散列码被用作存储在该表中值的索引。
import java.util.HashMap;
import java.util.Hashtable;
public class Demo01 {
public static void main(String[] args) {
// 创建hashtable对象
Hashtable<String, HashMap<String, String>> table = new Hashtable<>();
HashMap<String, String> map = new HashMap<>();
map.put("大锤", "DACHUI");
// 添加元素
table.put("DC", map);
// 获取哈希表的大小
System.out.println(table.size());
// 判断哈希表是否为空
System.out.println(table.isEmpty());
// 获取指定key的值
System.out.println(table.get("DC"));
}
}
属性(Properties)
Properties 继承于 Hashtable.Properties 类表示了一个持久的属性集.属性列表中每个键及其对应值都是一个字符串。Properties 类被许多Java类使用。例如,在获取环境变量时它就作为System.getProperties()方法的返回值。
Properties 继承于 Hashtable。表示一个持久的属性集.属性列表中每个键及其对应值都是一个字符串。Properties 类被许多 Java 类使用。例如,在获取环境变量时它就作为 System.getProperties() 方法的返回值。Properties 定义如下实例变量.这个变量持有一个 Properties 对象相关的默认属性列表。
将数据写入到文件当中
public class Demo01 { public static void main(String[] args) throws Exception { // 创建properties对象 Properties p = new Properties(); // 创建文件字节流对象 FileOutputStream fow = new FileOutputStream("./dir/p2.properties"); // 创建转换流对象 OutputStreamWriter osw = new OutputStreamWriter(fow, "UTF-8"); // 定义换成字符流 BufferedWriter bw = new BufferedWriter(osw); p.setProperty("driver", "com.jdbc.driver.Driver"); p.setProperty("DC", "我是大锤"); // 创建字符串输出流对象 PrintWriter w = new PrintWriter(bw, true); /** * 以适合使用 load(InputStream)方法加载到 Properties 表中的格式, * 将此 Properties 表中的属性列表(键和元素对)写入输出流。 */ p.store(w, "自定义properties文件数据");
读取属性
public class Demo02 { public static void main(String[] args) throws Exception { // 创建properties对象 Properties p = new Properties(); BufferedReader br = new BufferedReader( new InputStreamReader( new FileInputStream("./dir/p2.properties"), "utf-8" ) ); // 从输入流中读取属性列表(键和元素对)。 p.load(br); // 读取属性 String username = p.getProperty("DC"); System.out.println(username); String password = p.getProperty("driver"); System.out.println(password); String url = p.getProperty("url"); System.out.println(url); } }
队列(Queue)
Queue是java中实现队列的接口,它总共只有6个方法,我们一般只用其中3个就可以了。Queue的实现类有LinkedList和PriorityQueue。最常用的实现类是LinkedList。
Queue的6个方法分类:
压入元素(添加):add()、offer() 相同:未超出容量,从队尾压入元素,返回压入的那个元素。 区别:在超出容量时,add()方法会对抛出异常,offer()返回false
弹出元素(删除):remove()、poll() 相同:容量大于0的时候,删除并返回队头被删除的那个元素。 区别:在容量为0的时候,remove()会抛出异常,poll()返回false
获取队头元素(不删除):element()、peek() 相同:容量大于0的时候,都返回队头元素。但是不删除。 区别:容量为0的时候,element()会抛出异常,peek()返回null。
队列除了基本的 Collection 操作外,还提供特有的插入、提取和检查操作(如上)。每个方法都存在两种形式:一种抛出异常(操作失败时),另一种返回一个特殊值(null 或 false,具体取决于操作)。插入操作的后一种形式是用于专门为有容量限制的 Queue 实现设计的;在大多数实现中,插入操作不会失败。
双端队列
public class DequeDemo01 { public static void main(String[] args) { // 创建双端队列 Deque<String> dq = new LinkedList<>(); // 将元素添加到队列的末尾 dq.offer("乔峰"); dq.offer("虚竹"); dq.offer("段誉"); System.out.println(dq); // 在此deque的前面插入指定的元素 dq.offerFirst("扫地僧"); System.out.println(dq); // offerLast(E e) //在此deque的末尾插入指定的元素 dq.offerLast("慕容复"); System.out.println(dq); /* * 从队首取元素 */ System.out.println(dq.pollFirst()); /* * 从队尾取元素 */ System.out.println(dq.pollLast()); } }
队列基本的操作
public class QueueDemo01 {
public static void main(String[] args) {
/**
* queue队列的特点:
* 先进先出(单项队列)
*
* 常用方法:
* 添加元素:offer()
* 出队方法:poll()
* 查看队头元素:peek()
*/
// 创建queue对象
Queue<String> queue = new LinkedList<>();
// 获取队列的大小
int size = queue.size();
System.out.println(size);
// 元素入队
queue.offer("大锤");
queue.offer("张三");
queue.offer("李四");
System.out.println("查看队头元素:" + queue.peek());
size = queue.size();
System.out.println(size);
System.out.println("**********************************************");
// 元素出队
for (int i = 0; i < 3; i++) {
// 取出元素
String poll = queue.poll();
System.out.println(poll);
size = queue.size();
System.out.println(size);
}
}
}
XML基础_Java解析XML
XML基础
XML(可扩展标记语言)是一种很流行的简单的基于文本的语言来用作应用程序之间的通信模式。它被认为是传输标准装置和存储数据。JAVA提供了极好的支持和丰富的库来解析,修改或查询XML文档。
XML是一种简单的基于文本的语言,它被设计为储存和运输以纯文本格式的数据。它代表着可扩展标记语言。以下是一些XML的显着特征。 XML是一种标记语言。 XML是一种标记语言就像HTML一样。 XML标签不是像HTML那样预定义。 可以定义自己的标签,这就是为什么它被称为可扩展的语言。 XML标签被设计成自描述性的。 XML是W3C推荐用于数据存储和传输。
XML能干什么?
描述数据、存储数据、传输(交换)数据。
优缺点:
优势 以下是XML提供的优势: 技术无关 - 作为普通文本,XML是技术独立。它可以用于由任何技术进行数据的存储和传输的目的。 人类可读 - XML使用简单的文本格式。它是人类可读和可以理解的。 可扩展性 - 在XML,自定义标签可以创建和很容易使用。 允许验证 - 使用XSD,DTD和XML结构可以很容易地验证。
缺点 下面是使用XML的缺点: 冗余的语法 - 通常XML文件中包含大量的重复计算。 冗余 - 作为一个冗长的语言,XML文件大小增加了传输和存储成本。
<?xml version="1.0" encoding="UTF-8" ?> <!--xml声明必须位于文件的第一行--> <!--注释--> <!--一个xml文件当中智能有一个根标签--> <users><!--根标签--> <user id="DC"> <username zs="zhangsan" pwd="密码"></username> </user> <xml> 不推荐 </xml> <user class="cls" /> 不属于user标签内容 </users><!--跟标签结束标签-->
XML语法
1、声明:<?xml version="1.0" encoding="UTF-8"?>
2、根节点:必须只能有一个根节点
3、标签:标签必须有结束且区分大小写,标签必须顺序嵌套
4、属性:必须引号引起值 5、空格会被保留,HTML空格最多保留一个
6、命名规则:命名必须见名知意 a)名字可包含字母、数字以及其他的字符 b)名字不能以数字或者标点符号开始 c)名字不能以字符“xml”(或者XML、Xml)开始
7、名字不能包含空格
8、 不应在 XML 元素名称中使用 ":" ,这是由于它用于命名空间(namespaces)的保留字。
9、标签优先于属性。
10、XML 命名空间可提供避免元素命名冲突的方法。
11、CDATA:字符数据,<![CDATA[字符数据]]> ,字符数据不进行转义
12、实体:&实体;
<?xml version="1.0" encoding="UTF-8" ?>
<!--定义根标签-->
<users>
<!--描述一个用户-->
<user>
<username id="ZS">张三</username>
<password>123456</password>
<sex>男</sex>
<phone>13131145566</phone>
<address>中国北京</address>
</user>
<user>
<username id="LS">李四</username>
<password>123456</password>
<sex>男</sex>
<phone>13131145566</phone>
<address>中国北京</address>
<other>我会飞</other>
</user>
<user>
<username id="DC">大锤</username>
<password>123456</password>
<sex>男</sex>
<phone>13131145566</phone>
<address>中国北京</address>
</user>
<!--。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。-->
<user>
<username id="ZS">张三</username>
<password>123456</password>
<sex>男</sex>
<phone>13131145566</phone>
<address>中国北京</address>
<user>
<username id="ZS">张三</username>
<password>123456</password>
<sex>男</sex>
<phone>13131145566</phone>
<address>中国北京</address>
</user>
</user>