目录
一、配置文件
1.1 xml
1.1.1 xml概述
XML的全称为(EXtensible Markup Language),是一种可扩展的标记语言
标记语言: 通过标签来描述数据的一门语言(标签有时我们也将其称之为元素)
可扩展:标签的名字是可以自定义的,XML文件是由很多标签组成的,而标签名是可以自定义的
1.1.2 xml作用
- 用于进行存储数据和传输数据
- 作为软件的配置文件
1.1.3 作为配置文件的优势
- 可读性好
- 可维护性高
1.1.4 xml标签的规则
1. 标签有一堆尖括号和合法的标识符组成
<student>
2. 标签必须成对出现
<student></student>
3. 特殊的标签可以不成对,但是必须写结束标签
</address>
4. 标签中可以定义属性,属性和标签名用空格隔开,属性值必须用引号
<student id="1"></student>
5. 标签需要正确的嵌套
正确
<student id="1">
<name>张三</name>
</student>
错误
<student id="1">
<name>张三</student>
</name>
1.1.5 xml语法规则
1. xml文件的后缀必须是xml
2. 文档声明必须是第一行第一列, 注释也不能写第一行
<?xml version="1.0" encoding="UTF-8" standalone="yes/no" ?> version: 必须存在 encoding: 不是必须存在, 表示当前xml字符集, 一般都是UTF-8 standalone: 不是必须存在, 表示当前xml文件是否依赖其他xml, 取值为yes或者no
3. 必须存在一个根标签, 有且只能有一个
4. xml文件中可以定义注释信息, 格式为<!-- 注释内容 -->
5. xml文件中可以定义一下特殊字符
< < 小于
> > 大于
& & 和号
' ' 单引号
" " 双引号
6. xml文件中可以存在CDATA区
<![CDATA[...内容...]]>
代码示例
<?xml version="1.0" encoding="UTF-8" ?>
<!--文档声明必须在文件的第一行第一列, 注释也不能写第一行-->
<!--注释的快捷键: Ctrl+/-->
<students>
<student id="1">
<name>zhangsan</name>
<age>18</age>
<info><<<>>></info>
<!--CDATA区中可以写简单的文本, 不用复杂的符号代替-->
<message><![CDATA[内容<<< >>>]]></message>
</student>
<student id="2">
<name>lisi</name>
<age>24</age>
</student>
</students>
1.1.6 xml的DOM解析思想
1.DOM解析思想?
DOM(document Object Model) 文档对象模型
将文档的各个组成部分看做是对应的对象
首先会将xml文件全部加载到内存, 在内存中形成一个树状结构, 在获取对应的值
2.对象分类
1. Document对象: 整个xml文档
2. Element对象: 所有标签 ->
3. Attribute对象: 所有属性 -> 父类 -> Node对象
4. Text对象: 所有文本内容 ->
重点记忆!
DOM解析思想就是一层一层的进入, 一层一层的解析
1.1.7 xml解析代码实现
案例需求:
1. 解析这个xml文件
2. 将解析的数据封装到学生对象中
3. 将学生对象存储到ArrayList集合中
4. 遍历集合
1. xml文件
代码示例
<?xml version="1.0" encoding="UTF-8" ?>
<!--注释的内容-->
<!--本xml文件用来描述多个学生信息-->
<students>
<!--第一个学生信息-->
<student id="1">
<name>张三</name>
<age>23</age>
</student>
<!--第二个学生信息-->
<student id="2">
<name>李四</name>
<age>24</age>
</student>
</students>
2. javaBean类
代码示例
public class Student {
private String id;
private String name;
private int age;
public Student() {
}
public Student(String id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
3. 测试类
利用Dom4j解析xml文件
代码示例
public class XmlParse {
public static void main(String[] args) throws DocumentException {
//1.获取一个解析器对象
SAXReader saxReader = new SAXReader();
//2.利用解析器把xml文件加载到内存中,并返回一个文档对象
Document document = saxReader.read(new File("myxml\\xml\\student.xml"));
//3.获取到根标签
Element rootElement = document.getRootElement();
//4.通过根标签来获取student标签
//elements():可以获取调用者所有的子标签.会把这些子标签放到一个集合中返回.
//elements("标签名"):可以获取调用者所有的指定的子标签,会把这些子标签放到一个集合中并返回
//List list = rootElement.elements();
List<Element> studentElements = rootElement.elements("student");
//System.out.println(list.size());
//用来装学生对象
ArrayList<Student> list = new ArrayList<>();
//5.遍历集合,得到每一个student标签
for (Element element : studentElements) {
//element依次表示每一个student标签
//获取id这个属性
Attribute attribute = element.attribute("id");
//获取id的属性值
String id = attribute.getValue();
//获取name标签
//element("标签名"):获取调用者指定的子标签
Element nameElement = element.element("name");
//获取这个标签的标签体内容
String name = nameElement.getText();
//获取age标签
Element ageElement = element.element("age");
//获取age标签的标签体内容
String age = ageElement.getText();
//System.out.println(id);
//System.out.println(name);
//System.out.println(age);
Student s = new Student(id,name,Integer.parseInt(age));
list.add(s);
}
//遍历操作
for (Student student : list) {
System.out.println(student);
}
}
}
1.2 DTD约束
1.2.1 编写DTD
1. 什么是xml约束?
用来限定xml文件中可以使用的标签以及属性 -> 告诉程序员xml该怎么写
2. 约束分类
1. DTD
2. schema
步骤
1. 创建一个文件, 后缀为.dtd 步骤
2. 看xml文件中使用了哪些元素, <!ELEMENT>可以定义元素 步骤
3. 判断简单元素和复杂元素 (后面详细讲解)
* 简单元素: 没有子元素 <!ELEMENT 元素名称 (#PCDATA)> #PCDATA表示是字符串类型
* 复杂元素: 有子元素 <!ELEMENT 元素名称 (子元素名称1,子元素名称2...)>
代码示例
<!ELEMENT persons (person)> //复杂元素
<!ELEMENT person (name,age)> //复杂元素
<!ELEMENT name (#PCDATA)> //简单元素
<!ELEMENT age (#PCDATA)> //简单元素
1.2.2 引入DTD
引入DTD约束的三种方法
引入本地dtd
在xml文件内部引入
引入网络dtd
方式一: 引入本地dtd
1. 提前写好persondtd.dtd文件
<!ELEMENT persons (person)>
<!ELEMENT person (name,age)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
2. 在person.xml文件中引入persondtd.dtd约束
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE persons SYSTEM 'persondtd.dtd'> //引入dtd文件
<persons>
<person>
<name>张三</name>
<age>23</age>
</person>
</persons>
方式二: 在xml文件内部引入
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE persons [
<!ELEMENT persons (person)>
<!ELEMENT person (name,age)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
]>
<persons>
<person>
<name>张三</name>
<age>23</age>
</person>
</persons>
方式三: 引入网络dtd
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE persons PUBLIC "dtd文件的名称" "dtd文档的URL">
<persons>
<person>
<name>张三</name>
<age>23</age>
</person>
</persons>
1.2.3 DTD语法规则- 定义元素
定义元素格式为:
<!ELEMENT 元素名 元素类型>
简单元素: EMPTY表示标签体为空
ANY表示标签体可以为空, 也可以不为空
PCDATA表示元素内容为字符串 (常用)
复杂元素: 跟一个小括号中直接写元素名称
多个子元素可以用,号或者|隔开
,号表示元素的顺序
|表示子元素只能出现一个 在元素后面可以使用
?表示出现零次或一次
+表示出现一次或多次
*表示零次或多次
如果不写则表示只能出现一次
<!ELEMENT persons (person+)> //表示person标签可以出现一次或多次
<!ELEMENT person (name,age)> //表示name和age只能出现出现一次
<!ELEMENT name (#PCDATA)> //表示name是字符串
<!ELEMENT age (#PCDATA)> //表示age是字符串
1.2.4 语法规则- 定义属性
格式:
<!ATTLIST 元素名称 属性名称 属性类型 属性约束>
属性类型:
CDATA类型: 普通字符串
属性约束:
#REQUIRED 代表必须的
#IMPLIED 代表不是必须的
#FIXED "1p" value 代表属性值固定的
<!ATTLIST person id CDATA #FIXED "p1"> //表示必须写成p1
<!ATTLIST person id CDATA #REQUIRED> //表示id必须有值, 值随便写
代码示例
<!ELEMENT persons (person+)>
<!ELEMENT person (name,age)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ATTLIST person id CDATA #REQUIRED>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE persons SYSTEM 'persondtd.dtd'>
<persons>
<person id="001">
<name>张三</name>
<age>23</age>
</person>
<person id = "002">
<name>张三</name>
<age>23</age>
</person>
</persons>
1.3 dtd和schema-schema的区别
schema和dtd的区别?
1. schema约束文件也是一个xml文件, 符合xml语法, 这个文件的后缀名为.xsd
2. 一个xml中可以引入多个schema约束文件, 多个schema使用"名称空间"区分 (类似java的包名)
3. DTD中元素的类型比较单一, 常见的是PCDATA, 但是在schema中支持多种元素类型
4. schema语法更加复杂
注意, 理解记忆!
schema可以约束其他xml文件
但是schema本身也是一个xml, 所以也被其他文件约束着
1.3.1 编写schema约束
步骤
1. 创建文件后缀为.xsd
2. 定义文档声明: <?xml version="1.0" encoding="UTF-8" ?>
3. schema文件的根标签为: <schema>, 属性有三个 xmlns="http://www.w3.org/2001/XMLSchema "
targetNamespace="唯一的自定义URL地址"
固定格式表示文件质量良好: elementFormDefault="qualified
4. 通过element定义根标签: <element name="根标签名">
5. 判断复杂元素和简单元素, 复杂元素需要写<complexType>和<sequence>
<?xml version="1.0" encoding="UTF-8" ?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://"
elementFormDefault="qualified"
>
<!--定义persons复杂元素-->
<element name="persons">
<complexType>
<sequence>
<!--定义person复杂元素-->
<element name = "person">
<complexType>
<sequence>
<!--定义name和age简单元素-->
<element name = "name" type = "string"></element>
<element name = "age" type = "string"></element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
1.3.2 引入schema
步骤
1. 在根标签定义属性
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" //instance表示约束别人 xmlns="引入约束文件的名称空间"
2. 由于有两个xmlns, 给某一个xmlns属性添加标识:xsi
3. 通过xsi:schemaLocation="名称空间 文件路径"
<?xml version="1.0" encoding="UTF-8" ?>
<persons
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.itheima.cn/javase"
xsi:schemaLocation="http://www.itheima.cn/javase carschema.xsd"
>
<person>
<name>张三</name>
<age>23</age>
</person>
</persons>
1.3.3 schema定义属性
schema定义属性
在约束文件中</sequence>后</complexType>前书写
<attribute name="id" type="string" use="required"></attribute>
use="required" 必须的
use="optional" 可选的
1. 创建xsd文件
<?xml version="1.0" encoding="UTF-8" ?>
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www."
elementFormDefault="qualified"
>
<!--定义persons复杂元素-->
<element name="persons">
<complexType>
<sequence>
<!--定义person复杂元素-->
<element name = "person">
<complexType>
<sequence>
<!--定义name和age简单元素-->
<element name = "name" type = "string"></element>
<element name = "age" type = "string"></element>
</sequence>
<!--定义属性,required( 必须的)/optional( 可选的)-->
<attribute name="id" type="string" use="required"></attribute>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
2. xml中使用id属性
<?xml version="1.0" encoding="UTF-8" ?>
<persons
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.itheima.cn/javase"
xsi:schemaLocation="http://www.itheima.cn/javase carschema.xsd"
>
<person id="001">
<name>张三</name>
<age>23</age>
</person>
</persons>
二、枚举
2.1 概述
为了间接的表示一些固定的值,Java就给我们提供了枚举
是指将变量的值一一列出来,变量的值只限于列举出来的值的范围内
2.2 格式
public enum s {
枚举项1,枚举项2,枚举项3;
}
注意: 定义枚举类要用关键字enum
代码示例
// 定义一个枚举类,用来表示春,夏,秋,冬这四个固定值
public enum Season {
SPRING,SUMMER,AUTUMN,WINTER;
}
2.3 枚举的特点
1. 所有枚举类都是Enum的子类
2. 我们可以通过"枚举类名.枚举项名称"去访问指定的枚举项
3. 每一个枚举项, 其实就是该枚举类的一个对象 -> 重点记忆, 其他了解即可!
4. 枚举也是一个类, 也"可以声明成员变量"
5. 枚举类的"第一行上必须是枚举项", 如果没有后续代码, 最后一个枚举项后的分号可以省略, 不建议
6. 枚举类"可以有构造器, 但是必须是私有的", 默认是private的, 使用枚举项: 枚举(""){ };
7. 枚举类也"可以有抽象方法, 但是枚举项必须重写该方法"
代码示例
public enum Season {
SPRING("春"){
//如果枚举类中有抽象方法
//那么在枚举项中必须要全部重写
@Override
public void show() {
System.out.println(this.name);
}
},
SUMMER("夏"){
@Override
public void show() {
System.out.println(this.name);
}
},
AUTUMN("秋"){
@Override
public void show() {
System.out.println(this.name);
}
},
WINTER("冬"){
@Override
public void show() {
System.out.println(this.name);
}
};
public String name;
//空参构造
//private Season(){}
//有参构造
private Season(String name){
this.name = name;
}
//抽象方法
public abstract void show();
}
public class EnumDemo {
public static void main(String[] args) {
//我们可以通过"枚举类名.枚举项名称"去访问指定的枚举项
System.out.println(Season.SPRING);
System.out.println(Season.SUMMER);
System.out.println(Season.AUTUMN);
System.out.println(Season.WINTER);
//每一个枚举项其实就是该枚举的一个对象
Season spring = Season.SPRING;
}
}
2.4 枚举的方法
1. String name(); 获取枚举名称
2. int ordinal(); 返回枚举在枚举类中的索引值
3. int compareTo(E o); 比较两个枚举项, 返回索引差值
4. String toString(); 返回枚举常量名称
5. static <T> T valueOf(Class<T> type, String name);获取指定枚举类中指定名称的枚举值
6. values(); 获得所有枚举项
代码示例
public class Test {
public static void main(String[] args) {
//1. String name(); 获取枚举名称
String name = Week.MONDAY.name();
System.out.println(name); //MONDAY
System.out.println("------------------------");
//2. int ordinal(); 返回枚举在枚举类中的索引值
System.out.println(Week.MONDAY.ordinal()); //0
System.out.println(Week.TUESDAY.ordinal()); //1
System.out.println(Week.WEDNESDAY.ordinal()); //2
System.out.println(Week.THURSDAY.ordinal()); //3
System.out.println(Week.FRIDAY.ordinal()); //4
System.out.println(Week.SATURDAY.ordinal()); //5
System.out.println(Week.SUNDAY.ordinal()); //6
System.out.println("------------------------");
//3. int compareTo(E o); 比较两个枚举项, 返回索引差值
System.out.println(Week.MONDAY.compareTo(Week.SUNDAY)); //0 - 6 = -6
System.out.println("------------------------");
//4. String toString(); 返回枚举常量名称
String mondayValue = Week.MONDAY.toString();
System.out.println(mondayValue); //MONDAY 一般不会直接用,
System.out.println("------------------------");
//5. static <T> T valueOf(Class<T> type, String name);获取指定枚举类中指定名称的枚举值
Week monday = Enum.valueOf(Week.class, "MONDAY");
System.out.println(monday); //MONDAY
System.out.println(Week.MONDAY == monday); //true
System.out.println("------------------------");
//6. values(); 获得所有枚举项
Week[] week = Week.values();
for (Week value : week) {
// 打印枚举项
System.out.println(value);
/*
MONDAY
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY
*/
}
}
}
//枚举星期
enum Week{
MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY;
}
三、注解
3.1 概述
对我们的程序进行标注和解释
3.2 注解和注释的区别
注释:解释说明代码,给程序员看的
注解:对代码进行解释说明,给计算机看
3.3 使用注解进行配置配置的优势
代码更加简洁,方便
注解:一般用来替换配置文件
3.4 注解的本质
注解其实就是个接口,注解中的属性,本质上就是抽象方法,所有的注解,都默认继承自
java.lang.annotation.Annotation
public interface MyAnno1 extends java.lang.annotation.Annotation {
public abstract int age();
}
3.4 自定义注解
3.4.1 格式
格式:
public @interface 注解名{
//属性列表
//属性的格式 数据类型 属性名() [default 默认值];
}
属性的数据类型:
a. 基本数据类型都支持(byte short char int float double boolean long)
b. String
c. 枚举
d. Class
e. 注解
f. 以上类型的一维数组
代码示例
public @interface MyAnno1 {
//数据类型 属性名() [default 默认值];
//1.基本数据类型 四类八种
//2.String
//3.Class
//4.枚举
//5.注解本身
//6.以上类型的一维数组
int a() default 23;
String name() default "zhangsan";
Class clazz() default MyAnno2.class;
MyAnno3 anno() default @MyAnno3;
Season season() default Season.SPRING;
int[] arr() default {1, 2, 3, 4, 5};
Season[] seasons() default {Season.SPRING, Season.SUMMER};
String value();
}
3.4.2 使用注解
@注解名(属性名=值,属性名=值...)
3.4.3 注解使用细节
a. 如果给一个数组类型的属性赋值,并且只有一个元素,那么{}可以省略
b. 如果只需要给一个属性赋值,并且该属性的名字为value,那么 value=可以省略
1.1. 测试类
@MyAnno2("林志玲")
public class AnnoDemo{
}
1.2. 自定义注解类
public @interface MyAnno2 {
int a() default 23;
String value();
}
2.1 测试类
@MyAnno3(arr = 1)
public class AnnoDemo{
}
2.2 自定义注解类
public @interface MyAnno3 {
int[] arr();
}
3.5 元注解
概念:jdk提供的,用来修饰其它注解的注解
组成
组成: @Target():当前这个注解可以用在那些地方 ElementType.TYPE: 表示Anno这个注解可以使用到类上 ElementType.METHOD:表示Anno这个注解可以使用在方法上 ElementType.FIELD:表示Anno可以使用在成员变量上 ElementType.PARAMETER:表示Anno这个注解可以使用在参数上
@Retention:当前这个注解可以在那些阶段保留(默认是源码阶段) 阶段:源码、字节码、运行时 RetentionPolicy.RUNTIME:运行时 RetentionPolicy.CLASS:字节码 RetentionPolicy.SOURCE:源码
@Inherited:当前注解是否可以被子类继承
@Documented:当前注解是否可以被抽取到帮助文档中
1. 自定义注解
//定义注解
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD,ElementType.PARAMETER})
//表明注解在类、方法、成员变量、参数上使用
@Retention(RetentionPolicy.RUNTIME)//表示注解保留在运行阶段
public @interface Couple {
String man();
String woman();
}
2.测试类
isAnnotationPresent()判断有没有注解
getAnnotation()获取这个注解
@Couple(man = "李某人",woman ="马凡舒")//2.使用注解
public class MyTest {
public static void main(String[] args) {
//3.解析注解
//3.1找到当前MyTest这个类的字节码文件描述对象Class
Class clazz = MyTest.class;
//3.2判断有没有@Couple注解
//isAnnotationPresent()
boolean flag = clazz.isAnnotationPresent(Couple.class);
if(flag){
//3.3.获取@Couple这个注解
Couple couple = (Couple) clazz.getAnnotation(Couple.class);
//3.4获取属性值
String man = couple.man();
String woman = couple.woman();
//3.5打印结果
System.out.println(man+"和"+woman+"结婚了");
}
}
}