day17 配置文件、枚举、注解

目录

一、配置文件

1.1 xml

1.1.1 xml概述

1.1.2 xml作用

1.1.3 作为配置文件的优势

1.1.4 xml标签的规则

1.1.5 xml语法规则

1.1.6  xml的DOM解析思想

1.1.7 xml解析代码实现

1.2 DTD约束

1.2.1 编写DTD

1.2.2 引入DTD

1.2.3 DTD语法规则- 定义元素

1.2.4 语法规则- 定义属性

1.3 dtd和schema-schema的区别

1.3.1 编写schema约束

1.3.2 引入schema

1.3.3 schema定义属性

二、枚举

2.1 概述

2.2 格式

2.3 枚举的特点

2.4 枚举的方法

三、注解

3.1 概述

3.2 注解和注释的区别

3.3 使用注解进行配置配置的优势

3.4 注解的本质

3.4 自定义注解

3.4.1 格式

3.4.2 使用注解

3.4.3 注解使用细节

3.5 元注解


一、配置文件

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文件中可以定义一下特殊字符

        &lt; < 小于

        &gt; > 大于

        &amp; & 和号

        &apos; ' 单引号

        &quot; " 双引号

6. xml文件中可以存在CDATA区

        <![CDATA[...内容...]]>

代码示例

<?xml version="1.0" encoding="UTF-8" ?>

<!--文档声明必须在文件的第一行第一列, 注释也不能写第一行-->
<!--注释的快捷键: Ctrl+/-->

    <students>
        <student id="1">
            <name>zhangsan</name>
            <age>18</age>
            <info>&lt;&lt;&lt;&gt;&gt;&gt;</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+"结婚了");
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值