package com.it.demo01_junit;

/*
    案例: 演示Junit入门.

    Junit简介:
        概述:
            它是Java提供的一个进行测试的框架, 属于白盒测试, 简单理解: 它就是用来替代main方法的,
            即: 代码可以不用放到main方法中, 直接执行.
        细节;
            Junit只针对于 无参 无返回值的 非静态方法有效.
        使用步骤:
            1. 在项目下新建一个 libs文件夹, 用来存放第三方jar包.
            2. 把当前jar包配置到 classpath环境变量中.
                选中jar包, 右键 -> add as...
            3. 在使用该jar包的内容时, 需要先导包.
 */

import org.junit.Test;

//测试: 调用show()方法
public class Demo01 {
    @Test
    public void show(){
        System.out.println("show 方法");
    }

   /* @Test
    public void method() {
        show(10);
    }*/
}
package com.it.demo01_junit;

/*
    案例: 演示Junit单元测试的常用注解.

    Junit简介:
        概述:
            它是Java提供的一个进行测试的框架, 属于白盒测试, 简单理解: 它就是用来替代main方法的,
            即: 代码可以不用放到main方法中, 直接执行.
        细节;
            Junit只针对于 无参 无返回值的 非静态方法有效.
        使用步骤:
            1. 在项目下新建一个 libs文件夹, 用来存放第三方jar包.
            2. 把当前jar包配置到 classpath环境变量中.
                选中jar包, 右键 -> add as...
            3. 在使用该jar包的内容时, 需要先导包.
        常用注解:
            @Test       具体要进行单元测试(要执行)的代码
            @Before     会在@Test内容之前(自动)执行.
            @After      会在@Test内容之后(自动)执行.
 */

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

//测试: 调用show()方法
public class Demo02 {

    @Before
    public void init() {
        System.out.println("这里一般写一些初始化的操作");
        System.out.println("我会在@Test之前执行.");
    }

    @Test
    public void show(){
        System.out.println("show 方法");
    }


    @Test
    public void method(){
        System.out.println("method 方法");
    }

    @After
    public void destroy() {
        System.out.println("我会在@Test之后执行.");
        System.out.println("这里边一般写一些释放资源的动作");
    }


}

这个是在eclipse下操作步骤

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 下面介绍idea的搭建,其他的编译器不推荐使用

1.eclipse免费安装方便,新版本还用起来还可以

2. idea 个人用破解版很多,也很火,像别的myeclipse 就那吊样说是集成了很多插件和eclipse一样可以配

而且要买,而且大的一批,实话说我觉得这种人很low,还爱装逼,idea插件安装方便用起来很爽。Netbeans

这玩意说是开源的但是么人用,这个软件有个有趣的故事大家不妨百度一哈。

 

类加载的描述

  • 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过类的加载,类的连接,类的初始化这三个步骤来对类进行初始化。如果不出现意外情况,JVM将会连续完成这三个步骤,所以有时也把这三个步骤统称为类加载或者类初始化

 

 

类的加载

  • 就是指将class文件读入内存,并为之创建一个 java.lang.Class 对象
  • 任何类被使用时,系统都会为之建立一个 java.lang.Class 对象
  • 类的连接
    •   验证阶段:用于检验被加载的类是否有正确的内部结构,并和其他类协调一致
    •   准备阶段:负责为类的类变量(静态成员变量)分配内存,并设置默认初始化值
    •   解析阶段:将类的二进制数据中的符号引用替换为直接引用
  • 类的初始化
    •   在该阶段,主要就是对类变量进行初始化
  • 类的初始化步骤
    •   假如类还未被加载和连接,则程序先加载并连接该类
    •   假如该类的直接父类还未被初始化,则先初始化其直接父类
    •   假如类中有初始化语句,则系统依次执行这些初始化语句
    •   注意:在执行第2个步骤的时候,系统对直接父类的初始化步骤也遵循初始化步骤1-3
  • 类的初始化时机
  • 创建类的实例
    •   调用类的类方法
    •   访问类或者接口的类变量,或者为该类变量赋值
    •   使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
    •   初始化某个类的子类
    •   直接使用java.exe命令来运行某个主类
  • 类加载器
  • 类加载器的作用
  • 负责将.class文件加载到内存中,并为之生成对应的 java.lang.Class 对象。虽然我们不用过分关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行!

JVM的类加载机制

  • 全盘负责:就是当一个类加载器负责加载某个Class时,该Class所依赖的和引用的其他Class也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入
  • 父类委托:就是当一个类加载器负责加载某个Class时,先让父类加载器试图加载该Class,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类
  • 缓存机制:保证所有加载过的Class都会被缓存,当程序需要使用某个Class对象时,类加载器先从缓存区中搜索该Class,只有当缓存区中不存在该Class对象时,系统才会读取该类对应的二进制数据,并将其转换成Class对象,存储到缓存区

Java中的内置类加载器

  • Bootstrap class loader:它是虚拟机的内置类加载器,通常表示为null ,并且没有父null
  • Platform class loader:平台类加载器可以看到所有平台类 ,平台类包括由平台类加载器或其祖先定义的Java SE平台API,其实现类和JDK特定的运行时类
  • System class loader:它也被称为应用程序类加载器 ,与平台类加载器不同。 系统类加载器通常用于定义应用程序类路径,模块路径和JDK特定工具上的类
  • 类加载器的继承关系:System的父加载器为Platform,而Platform的父加载器为Bootstrap

 

package com.it.demo02_classloader;

/*
    案例: 演示各个类加载器.

    类加载器简介:
        概述:
            指的是ClassLoader, 主要是用来 加载字节码文件(.class文件)进内存.
        什么时候才会加载.class字节码文件进内存?     //类加载的时机
            当你使用某个类的成员, 但是此时该类的字节码文件在内存中还不存在的时候, 类加载器就会加载该类的字节码文件进内存,
            并为之创建与其对应的 Class对象.
        JVM的类加载机制:
            全盘加载:
            缓存机制:
            父类委托:
        Java中类加载器的分类:
            BootStrapClassLoader: 根类加载器, 主要负责加载 jre/lib/rt.jar相关.
            ExtClassLoader: 扩展类加载器, 主要负责加载 jre/lib/ext/*.jar 相关
                            JDK1.9的时候更名为: PlatformClassLoader
            AppClassLoader: 应用程序类加载器, 主要负责加载 classpath环境变量配置的内容 和 用户自定义的类.
                            JDK1.9的时候更名为: SystemClassLoader
 */
public class Demo01 {
    public static void main(String[] args) {
        //这个代码只要能看懂就行.
        //1. 获取加载当前类的 类加载器.
        ClassLoader loader = ClassLoader.getSystemClassLoader();
        System.out.println(loader);                             //AppClassLoader
        System.out.println(loader.getParent());                 //ExtClassLoader
        /*
            这里理论上来讲打印的应该是: BootStrapClassLoader, 但是因为它的底层是通过C语言编写的,
            在Java中并没有与其对应的对象形式, 所以打印结果是: null
         */
        System.out.println(loader.getParent().getParent());     //null

    }
}
package com.it.pojo;

//学生类
public class Student {
    //属性
    public String name;
    private int age;

    //构造方法
    public Student() {
    }

    private Student(String name) {
        this.name = name;
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //成员方法
    public void show() {
        System.out.println("student show()方法");
    }

    public String show2(String s, int a) {
        System.out.println(s);
        System.out.println(a);
        return s + a;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }


    public void eat() {
        System.out.println("Student eat()方法");
    }

    public void sleep() {
        System.out.println("Student sleep()方法");
    }
}


package com.it.demo03_reflect;

import com.it.pojo.Student;

/*
    案例: 演示反射入门.

    反射简介:
        概述:
            反射指的就是在程序的运行期间, 通过 .class字节码来操作类中的成员(成员变量, 构造方法, 成员方法).
        获取字节码文件对象的3种方式:
            方式一: 通过 类名.class 方式获取.
            方式二: 通过 对象名.getClass()方法获取.
            方式三: 通过 反射方式获取.
                Class.forName("全类名");
        细节:
            1. 一个.java文件对应一个.class字节码文件对象, 一个.class字节码文件对象, 对应一个 Class对象.
            2. 获取字节码文件对象的3种方式的各自应用场景:
                 方式一: 通过 类名.class 方式获取.
                    一般是当做 同步的锁对象的.
                 方式二: 通过 对象名.getClass()方法获取.
                    一般是用来比较 两个对象是否是同一个类型对象的.
                 方式三: 通过 反射方式获取.
                    一般应用在反射中.

 */
public class Demo01_QuickStart {
    public static void main(String[] args) throws Exception {
        //需求: 获取Student类的字节码文件对象.
        // 方式一: 通过 类名.class 方式获取.
        Class<Student> clazz1 = Student.class;
        // 方式二: 通过 对象名.getClass()方法获取.
        Class<? extends Student> clazz2 = new Student().getClass();
        // 方式三: 通过 反射方式获取.
        Class<?> clazz3 = Class.forName("com.itheima.pojo.Student");

        System.out.println(clazz1 == clazz2);       //true
        System.out.println(clazz1 == clazz3);       //true
        System.out.println(clazz2 == clazz3);       //true
    }
}
package com.it.demo03_reflect;

import com.it.pojo.Student;

import java.lang.reflect.Constructor;
import java.rmi.server.ExportException;

/*
    案例: 演示反射操作构造方法(Constructor), 创建对象.

    Constructor类:
        表示构造器对象, 即: 构造方法的对象形式.

    涉及到的成员方法:
        Class类中的成员方法:
            public Constructor[] getConstructors();                         获取指定类中, 所有的构造器对象(不包含私有的)
            public Constructor getConstructor(Class... parameters);         根据参数, 获取指定的构造器对象(不包含私有的)
            public Constructor[] getDeclaredConstructors();                 获取指定类中, 所有的构造器对象(包含私有的)
            public Constructor getDeclaredConstructor(Class... parameters); 根据参数, 获取指定的构造器对象(包含私有的)
            public Object newInstance();                                    根据类中的空参构造, 创建该类的对象.

        Constructor类中的成员方法:
            public Object newInstance(Object... values);                    根据参数值, 创建指定类的对象.
 */
public class Demo02_Constructor {
    public static void main(String[] args) throws Exception {
        //需求: 根据类中的 公共的 无参构造, 创建该类的对象.
        //1. 获取该类的字节码文件对象.
        Class<?> clazz = Class.forName("com.itheima.pojo.Student");
        //方式一: 标准写法, 先获取构造器对象, 然后根据构造器对象创建指定的 对象.
       /* //2. 获取空参构造器对象.
        Constructor<?> con = clazz.getConstructor();
        //3. 根据空参构造器, 创建该类的对象.
        Student stu = (Student)con.newInstance();*/

        //方式二: 简单版, 该方式只针对于 公共的无参构造有效.
        Student stu = (Student)clazz.newInstance();
        //4. 打印对象即可.
        System.out.println(stu);
    }
}
package com.it.demo03_reflect;

import com.it.pojo.Student;

import java.lang.reflect.Constructor;

/*
    案例: 演示反射操作构造方法(Constructor), 四个方法详解.

    Constructor类:
        表示构造器对象, 即: 构造方法的对象形式.

    涉及到的成员方法:
        Class类中的成员方法:
            public Constructor[] getConstructors();                         获取指定类中, 所有的构造器对象(不包含私有的)
            public Constructor getConstructor(Class... parameters);         根据参数, 获取指定的构造器对象(不包含私有的)
            public Constructor[] getDeclaredConstructors();                 获取指定类中, 所有的构造器对象(包含私有的)
            public Constructor getDeclaredConstructor(Class... parameters); 根据参数, 获取指定的构造器对象(包含私有的)
            public Object newInstance();                                    根据类中的空参构造, 创建该类的对象.

        Constructor类中的成员方法:
            public Object newInstance(Object... values);                    根据参数值, 创建指定类的对象.
            public void setAccessible(boolean flag);                        传入true, 表示暴力反射, 即: 私有成员也可以直接使用.
 */
public class Demo03_Constructor {
    public static void main(String[] args) throws Exception {
        //需求: 根据类中的 公共的 无参构造, 创建该类的对象.
        //1. 获取该类的字节码文件对象.
        Class<?> clazz = Class.forName("com.itheima.pojo.Student");

        //2. 测试: 获取所有的非私有构造方法
        //method01(clazz);

        //3. 测试: 获取某个指定的公共的构造方法
        //method02(clazz);

        //4. 测试: 获取所有的构造方法, 包括私有
        //method03(clazz);

        //5. 测试: 获取某个指定的构造方法, 包括私有
        //method04(clazz);
    }

    public static void method04(Class<?> clazz) throws NoSuchMethodException, InstantiationException, IllegalAccessException, java.lang.reflect.InvocationTargetException {
        Constructor<?> con = clazz.getDeclaredConstructor(String.class);
        System.out.println(con);

        //暴力反射
        con.setAccessible(true);

        //通过私有的构造方法, 创建对象.
        Student stu = (Student)con.newInstance("赵丽颖");
        System.out.println(stu);
    }

    public static void method03(Class<?> clazz) {
        Constructor<?>[] cons = clazz.getDeclaredConstructors();
        for (Constructor<?> con : cons) {
            System.out.println(con);
        }
    }

    public static void method02(Class<?> clazz) throws NoSuchMethodException, InstantiationException, IllegalAccessException, java.lang.reflect.InvocationTargetException {
        Constructor<?> con = clazz.getConstructor(String.class, int.class);
        System.out.println(con);
        Student stu = (Student)con.newInstance("刘亦菲", 33);
        System.out.println(stu);
    }

    public static void method01(Class<?> clazz) {
        Constructor<?>[] cons = clazz.getConstructors();
        for (Constructor<?> con : cons) {
            System.out.println(con);
        }
    }
}
package com.it.demo03_reflect;

import com.it.pojo.Student;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

/*
    案例: 演示反射操作成员变量(Field), 四个方法详解.

    Field类:
        表示成员变量, 也叫: 对象变量, 字段.

    涉及到的成员方法:
        Class类中的成员方法:
            public Field[] getFields();                         获取指定类中, 所有的成员变量对象(不包含私有的)
            public Field getField(String name);                 根据字段名, 获取指定的成员变量对象(不包含私有的)
            public Field[] getDeclaredFields();                 获取指定类中, 所有的成员变量对象(包含私有的)
            public Field getDeclaredField(String name);         根据字段名, 获取指定的成员变量对象(包含私有的)

       Field类中的成员方法:
            public void set(Object obj, Object value);          设置obj对象的 filed属性 为指定的值(value)
            public void setAccessible(boolean flag);            传入true, 表示暴力反射, 即: 私有成员也可以直接使用.
 */
public class Demo04_Field {
    public static void main(String[] args) throws Exception {
        //需求: 根据类中的 公共的 无参构造, 创建该类的对象.
        //1. 获取该类的字节码文件对象.
        Class<?> clazz = Class.forName("com.itheima.pojo.Student");

        //2. 测试: 获取所有的非私有 成员变量
        //method01(clazz);

        //3. 测试: 获取某个指定的公共的 成员变量
        //method02(clazz);

        //4. 测试: 获取所有的 成员变量, 包括私有
        //method03(clazz);

        //5. 测试: 获取某个指定的 成员变量, 包括私有
        Field age = clazz.getDeclaredField("age");
        System.out.println(age);
    }

    public static void method03(Class<?> clazz) {
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field);
        }
    }

    public static void method02(Class<?> clazz) throws NoSuchFieldException {
        Field field = clazz.getField("name");
        System.out.println(field);
    }

    public static void method01(Class<?> clazz) {
        Field[] fields = clazz.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
    }
}
package com.it.demo03_reflect;

import com.it.pojo.Student;

import java.lang.reflect.Field;

/*
    案例: 演示反射操作成员变量(Field), 给私有的成员变量赋值.

    Field类:
        表示成员变量, 也叫: 对象变量, 字段.

    涉及到的成员方法:
        Class类中的成员方法:
            public Field[] getFields();                         获取指定类中, 所有的成员变量对象(不包含私有的)
            public Field getField(String name);                 根据字段名, 获取指定的成员变量对象(不包含私有的)
            public Field[] getDeclaredFields();                 获取指定类中, 所有的成员变量对象(包含私有的)
            public Field getDeclaredField(String name);         根据字段名, 获取指定的成员变量对象(包含私有的)

       Field类中的成员方法:
            public void set(Object obj, Object value);          设置obj对象的 filed属性 为指定的值(value)
            public void setAccessible(boolean flag);            传入true, 表示暴力反射, 即: 私有成员也可以直接使用.
 */
public class Demo05_Field {
    public static void main(String[] args) throws Exception {
        //需求: 给Student类中私有的age属性赋值.
        //1. 获取该类的字节码文件对象.
        Class<?> clazz = Class.forName("com.itheima.pojo.Student");
        //2. 获取该类的空参对象.
        Student stu = (Student)clazz.newInstance();
        //3. 获取私有的成员变量 age
        Field age = clazz.getDeclaredField("age");
        //4. 暴力反射
        age.setAccessible(true);
        //5. 给私有的成员变量 age设置值.
        age.set(stu, 33);
        System.out.println(stu);

    }
}
package com.it.demo03_reflect;

import com.it.pojo.Student;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/*
    案例: 演示反射操作成员方法(Method).

    Method类:
        表示成员方法, 也叫: 对象方法.

    涉及到的成员方法:
        Class类中的成员方法:
            public Method[] getMethods();                                       获取指定类中, 所有的成员方法对象(不包含私有的)
            public Method getMethod(String name, Class... parameters);          根据字段名 和 形参列表, 获取指定的成员方法对象(不包含私有的)
            public Method[] getDeclaredMethods();                               获取指定类中, 所有的成员方法对象(包含私有的)
            public Method getDeclaredMethod(String name, Class... parameters);  根据字段名 和 形参列表, 获取指定的成员方法对象(包含私有的)

      Method类中的成员方法:
            public Object invoke(Object obj, Object... values);  执行obj对象的method方法, values表示执行该方法时所需的参数, Object表示方法的返回值类型
            public void setAccessible(boolean flag);            传入true, 表示暴力反射, 即: 私有成员也可以直接使用.
 */
public class Demo06_Method {
    public static void main(String[] args) throws Exception {
        //需求1: 调用Student#show()
        //method01();

        //需求2: 调用Student#show2()
        //1. 获取该类的字节码文件对象.
        Class<?> clazz = Class.forName("com.itheima.pojo.Student");
        //2. 创建该类的对象.
        Student stu = (Student)clazz.newInstance();
        //3. 根据字节码文件对象, 获取 成员方法对象.
        Method method = clazz.getMethod("show2", String.class, int.class);
        //4. 执行成员方法
        String result = (String)method.invoke(stu, "abc", 10);       //表示执行: stu对象的show()方法
        //5. 打印方法执行后的结果
        System.out.println(result);
    }

    public static void method01() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        //1. 获取该类的字节码文件对象.
        Class<?> clazz = Class.forName("com.itheima.pojo.Student");
        //2. 创建该类的对象.
        Student stu = (Student)clazz.newInstance();
        //3. 根据字节码文件对象, 获取 成员方法对象.
        Method show = clazz.getMethod("show");
        //4. 执行成员方法
        show.invoke(stu);       //表示执行: stu对象的show()方法
    }
}
package com.it.demo05_properties;

import java.util.Properties;

/*
    案例: Properties集合类入门.

    Properties集合类简介:
        概述:
            它是双列集合的一种, 是Hashtable集合类的子类, 它比较特殊, 表示持久的属性集, 键和值都是String类型.
            它是唯一一个可以直接和IO流相结合使用的集合类, 即: 它可以直接从流中读取数据, 也可以写入到流中.
        成员方法:
            setProperty();          类似于HashMap#put(), 添加元素.
            getProperty();          类似于HashMap#get(), 根据键获取值.

            load(输入流对象);       从流中加载数据
            store(输出流对象);      可以直接把集合中的数据写到流中(文件中).
 */
public class Demo01 {
    public static void main(String[] args) {
        //1. 创建集合对象.
        Properties pp = new Properties();

        //2. 添加元素.
        pp.setProperty("name", "hangge");
        pp.setProperty("phone", "13112345678");

        //3. 根据键获取值.
        System.out.println("姓名: " + pp.getProperty("name"));
        System.out.println("手机号: " + pp.getProperty("phone"));

        //4. 打印集合
        System.out.println(pp);
    }
}
package com.it.demo05_properties;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;

/*
    案例: 演示Properties集合类 结合 IO流的用法.
 */
public class Demo02 {
    public static void main(String[] args) throws Exception {
        //需求1: 演示Properties加载文件中的数据.
        Properties pp = new Properties();
        //Properties加载文件中的数据.
        pp.load(new FileInputStream("day14/src/my.properties"));
        System.out.println(pp);             //phone=13112345678, age=18, name=hangge
        System.out.println(pp.get("name"));

        //需求2: 把数据写到文件中.
        //修改Properties集合中的属性值
        pp.setProperty("name", "hanghang");
        pp.setProperty("phone", "123456");
        pp.setProperty("address", "xinxiang");

        //把修改后的数据重新写到配置文件中.
        //第一个参数: 配置文件的路径.  第二个参数: 对于本次修改配置的描述信息, 即: 为啥修改配置文件, 谁修改的. 不要写中文, 会被识别为Unicode值.
        pp.store(new FileOutputStream("day14/src/my.properties"), "夯哥");
    }
}
package com.it.demo06_annnotation;

import java.util.Date;

/*
    案例: 演示注解入门.

    注解简介:
        概述:
            注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。
            它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
        作用分类:
            编写文档:通过代码里标识的注解生成文档【例如,生成文档doc文档】
            代码分析:通过代码里标识的注解对代码进行分析【例如,注解的反射】 (重要的,因为在框架中通常会采用注解的方式来代替配置文件,再通过反射获取注解中配置的信息)
            编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查【例如,Override】
        JDK中常用的3个注解
            @Override           表示方法重写
            @Deprecated         表示已过时.
            @SuppressWarnings   表示忽略所有的警告.

        结论(记忆):  我们关注的注解, 主要是关注它的一种最常用的用法:
            采用注解的方式来代替配置文件,再通过反射获取注解中配置的信息

 */

//@SuppressWarnings("unused")       表示忽略: 初始化了, 但是未使用的变量.
@SuppressWarnings("all")            //表示忽略: 所有的警告信息.
public class Demo01 {
    public static void main(String[] args) {
        //打印时间, 演示: 已过时的方法的格式.
        System.out.println(new Date().toLocaleString());

        //调用show()方法
        show();

        //初始化变量, 但是我们不用他
        int a = 10;
    }

    @Deprecated     //标记该方法已过时.
    public static void show() {
        System.out.println("show 方法");
    }
}
package com.it.demo06_annnotation;

/*
    案例: 演示自定义注解的格式和用法.

    自定义注解演示:
        格式:
            public @interface 注解名 {
                修饰符 数据类型 变量名() default 默认值;
                修饰符 数据类型 变量名() default 默认值;
                修饰符 数据类型 变量名() default 默认值;
            }
        细节:
            1. 注解的本质就是一个继承了 Annotation接口的 接口.
            2. 注解里边可以写什么:
                八种基本数据类型(int,float,boolean,byte,double,char,long,short)
                String类型,Class类型,枚举类型,注解类型
                以上所有类型的一维数组
 */

//表示自定义的注解
public @interface MyAnnotation {
    //第一个属性
    String name() default "张三"; //String类型,Class类型,枚举类型
    int age();                   //八种基本数据类型都可以
    MyAnnotation2 ma();          //注解类型

    String[] author();          //表示作者, 以上所有类型的一维数组形式.
}


//自定义的注解
@interface MyAnnotation2{

}
package com.it.demo08_xml;

/*
    案例: XML简介

    概述:
        XML也叫可扩展标记语言(Extensible Markup Language), 也是一门标签语言, 属于W3C公司(万维网联盟).
        标记语言解释: 即它是由标签语言组成的.
            <a></a>   前边的叫: 开始标签, 也叫开放标签,  后边的叫: 结束标签, 也叫闭合标签.
            <br />    像这样的标签叫: 自闭合标签

    xml 和 html之间的区别:
       xml标签都是自定义的,html标签是预定义。
       xml的语法严格,html语法松散。
       xml是存储数据的,html是展示数据。

    xml的组成部分:
        略, 详见讲义.

    xml的约束:
        概述:
            就是用来限定xml装能写啥, 不能写啥.
        分类:
            dtd约束:
                只能约束标签的子标签, 属性等, 不能做精细约束.
            schema约束:
                可以精准约束到 限定某个属性的值必须是谁.
 */
public class Demo01 {
}

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

<!--根标签, 一个xml文件中有且只能有一个.-->
<students>
    <!--表示具体的数据, 第一个元素-->
    <student id="001" color="red">
        <name>张三</name>
        <age>23</age>
    </student>

    <!--第二个元素-->
    <student id="002">
        <name>李四</name>
        <age>24</age>
    </student>
    &lt;前妻&gt;
    <br/>
    <hg></hg>
</students>
<!--这个就是dtd的约束文档-->

<!--这个是限定根标签必须是 students, 子标签是student, *表示0次或者多次-->
<!ELEMENT students (student*) >
<!--限定student标签的 子元素必须是 name, age, sex-->
<!ELEMENT student (name,age,sex)>
<!--限定name, age, sex三个标签的类型是: 简单类型, 类似于字符串-->
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!--限定student标签可以有一个number属性, 表示id属性, REQUIRED: 表示该属性值要唯一-->
<!ATTLIST student number ID #REQUIRED>wxwork


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

<!--引入student.dtd约束文件, 即: 该xml的规则必须满足 此约束文件的规则-->
<!DOCTYPE students SYSTEM "student.dtd">

<students>
    <student number="it_0001">
        <name>tom</name>
        <age>18</age>
        <sex>male</sex>
    </student>

    <student number="itcast_0002">
        <name>tom</name>
        <age>18</age>
        <sex>male</sex>
    </student>
    
</students>
package com.it.demo10_schema;

import java.util.Date;

public class Demo01 {
    public static void main(String[] args) {
        //需求: 创建Date对象.
        Date d = new Date();                //默认去 java.util包下找.

        java.sql.Date d2 = new java.sql.Date(0L);
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <context:annotation-config />

    <context:component-scan base-package="cn.cisol.mvcdemo">
        <context:include-filter type="annotation"
            expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    <mvc:annotation-driven />
    <mvc:resources mapping="/resources/**" location="/resources/" />

    <bean
        class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="order" value="1" />
        <property name="mediaTypes">
            <map>
                <entry key="json" value="application/json" />
                <entry key="xml" value="application/xml" />
                <entry key="htm" value="text/html" />
            </map>
        </property>

        <property name="defaultViews">
            <list>
                
                <bean
                    class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
                </bean>
            </list>
        </property>
        <property name="ignoreAcceptHeader" value="true" />
    </bean>

    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsps/" />
        <property name="suffix" value=".jsp" />
    </bean>


  
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="209715200" />
        <property name="defaultEncoding" value="UTF-8" />
        <property name="resolveLazily" value="true" />
    </bean>

</beans>
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 
    1.填写xml文档的根元素
    2.引入xsi前缀.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3.引入xsd文件命名空间.  xsi:schemaLocation="http://www.itcast.cn/xml  student.xsd"
    4.为每一个xsd约束声明一个前缀,作为标识  xmlns="http://www.itcast.cn/xml" 
    
    
 -->
 <students   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns="http://www.itcast.cn/xml" 
            xsi:schemaLocation="http://www.itcast.cn/xml  student.xsd"
             >
     <student number="heima_0001">
         <name>tom</name>
         <age>18</age>
         <sex>male</sex>
     </student>

    <student number="heima_0002">
        <name>tom</name>
        <age>18</age>
        <sex>female</sex>
    </student>

         
 </students>
<?xml version="1.0"?>

<!--
    因为Schema约束文件它的本质也是一个 xml文件, 所以它的定义格式要遵循 W3C公司的规范
    这里在做的事儿其实是引入 W3C公司针对于xml文件的规范.
-->
<xsd:schema xmlns="http://www.itcast.cn/xml"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.itcast.cn/xml" elementFormDefault="qualified">

    <!--元素标签 students的 数据类型是: 自定义类型 studentsType-->
    <xsd:element name="students" type="studentsType"/>

    <!--这里是studentsType类型的 具体的规则-->
    <xsd:complexType name="studentsType">
        <!--说明: studentsType类型的子元素是 student标签-->
        <xsd:sequence>
            <!--说明元素标签student的数据类型是: 自定义的数据类型 studentType, 该标签至少出现0次, 至多无所谓-->
            <xsd:element name="student" type="studentType" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
    </xsd:complexType>

    <!-- 以下是 自定义类型studentType的具体约束规则-->
    <xsd:complexType name="studentType">
        <!-- 说明student元素的子标签的顺序必须是: name, age, sex -->
        <xsd:sequence>
            <!--说明name标签, 类型是: 字符串(string)-->
            <xsd:element name="name" type="xsd:string"/>
            <!--说明age标签, 类型是: 自定义的数据类型 ageType-->
            <xsd:element name="age" type="ageType" />
            <!--说明sex标签, 类型是: 自定义的数据类型 sexType-->
            <xsd:element name="sex" type="sexType" />
        </xsd:sequence>

        <!--说明 自定义类型studentType 有一个 number属性, 属性的类型是: 自定义类型numberType, required: 值唯一-->
        <xsd:attribute name="number" type="numberType" use="required"/>
    </xsd:complexType>

    <!-- 以下是自定义的类型 sexType的 具体规则-->
    <xsd:simpleType name="sexType">
        <!--说明值是 字符串类型-->
        <xsd:restriction base="xsd:string">
            <!--说明值必须是: male 或者 female-->
            <xsd:enumeration value="male"/>
            <xsd:enumeration value="female"/>
        </xsd:restriction>
    </xsd:simpleType>

    <!-- 以下是自定义的类型 ageType的 具体规则-->
    <xsd:simpleType name="ageType">
        <!--说明值必须是: 数字类型, 且范围必须是: 0-256-->
        <xsd:restriction base="xsd:integer">
            <xsd:minInclusive value="0"/>
            <xsd:maxInclusive value="256"/>
        </xsd:restriction>
    </xsd:simpleType>

    <!-- 以下是自定义的类型 numberType的 具体规则-->
    <xsd:simpleType name="numberType">
        <!--说明值是 字符串类型-->
        <xsd:restriction base="xsd:string">
            <!--numberType的属性值格式必须是: heima_四个数字-->
            <xsd:pattern value="heima_\d{4}"/>
        </xsd:restriction>
    </xsd:simpleType>
</xsd:schema> 

 

posted on 2021-02-03 15:11  王平  阅读(72)  评论(0)    收藏  举报