同系列文章导读:【JavaSE】文章导读

所有文章均在本博客首发,其他平台同步更新

如有问题,欢迎指正(评论区留言即可)

发表评论时请填写正确邮箱,以便于接收通知【推荐QQ邮箱】


类加载器&反射

类加载器

  • 概述:负责将.class文件(存储的物理文件)加载到内存中
  • 加载时机

    • 创建类的实例(对象)
    • 调用类的类方法(静态方法)
    • 访问类或者接口的类变量,或者为该类变量赋值(静态变量)
    • 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
    • 初始化某个类的子类
    • 直接使用java.exe命令来运行某个主类

    用到就加载,不用不加载

  • 加载过程

    加载---验证---准备---解析---初始化

    又将验证---准备---解析这三步称为链接

加载

  • 通过一个类的全限定名来获取定义此类的二进制字节流(包名+类名;用流进行传输)
  • 将这个字节流所代表的静态存储结构转化为运行时数据结构(将这个类加载到内存中)
  • 在内存中生成一个代表这个类的java.lang.Class对象,任何类被使用时,系统都会为之建立一个java.lang.Class对象(加载完毕创建一个class对象)

链接

  • 验证:确保Class文件字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身安全(文件中的信息是否符合虚拟机规范、有没有安全隐患)
  • 准备:负责为类的类变量(静态变量)分配内存,并设置默认初始化值(初始化静态变量)
  • 解析:将类的二进制数据流中的符号引用替换为直接引用(本类中用到了其他类,此时就要找到对应的类)

初始化:根据程序员通过程序制定的主观计划去初始化类变量和其他资源(静态变量赋值以及初始化其他资源)

分类

  • 启动类加载器(Bootstrap ClassLoader):虚拟机内置的类加载器
  • 平台类加载器(Platform Classloader):负责加载JDK中一些特殊的模块(继承启动类加载器)
  • 系统类加载器(System Classloader):负责加载用户类路径上所指定的类库(继承平台类加载器)(用的最多)
  • 自定义类加载器(UserClassloader):自定义的类加载器(继承系统类加载器)(用的不多

双亲委派模型

  • 当使用最下层的类加载器加载字节码文件时,首先会把加载任务逐层委派给父类加载器,直到最顶层的启动类加载器中
  • 这些加载器都有各自的加载范围,当父类加载器无法完成加载请求时,就会一层层往下返回

ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();----可以获得系统类加载器

systemClassLoader.getParent()-------------得到父类加载器

常用方法

方法名说明
loadClass(String name, boolean resolve)加载指定名称(包括包名)的二进制类型
findClass(String name)当loadClass方法中父类加载失败时,调用自己的findClass方法来完成类加载
defineClass(byte[] b, int off, int len)将byte字节流解析成JVM能够识别的Class对象
resolveClass(Class c)让使用类的Class对象创建完成也同时被解析

反射

Java反射机制

  • 在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法
  • 对于任意一个对象,都能够调用它的任意属性和方法
  • 这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制

利用反射调用它类中的属性和方法时,无视修饰符。反射操作,程序比较灵活,动态的

先获取配置文件中的信息,动态获取信息并创建对象和调用方法

获取Class对象

以前调用一个类中的方法反射调用一个类中的方法
创建这个类的对象(new)反射方式:创建对象(利用Class对象)
用对象调用方法反射方式:调用方法
  • 源代码阶段:Class.forName(String className) 通过Class类静态方法传递全类名获取Class对象
  • Class对象阶段:类名.class
  • Runtime运行时阶段:对象.getClass()

获取Constructor对象

  • Constructor<?>[] getConstructors():返回所有公共构造方法对象的数组
  • Constructor<?>[] getDeclaredConstructors() :返回所有构造方法对象的数组(包括私有)
  • Constructor<T> getConstructor(Class<?>... parameterTypes):返回单个公共构造方法对象
  • Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes):返回单个构造方法对象(包括私有)

利用Constructor创建对象

  • T newInstance(Object...initargs):根据指定的构造方法创建对象
package fanshe;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Demo1 {

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
            // 获取字节码文件
            Class clazz = Class.forName("fanshe.Student");

            // 获取构造方法
            Constructor constructor = clazz.getConstructor(String.class, int.class);

            // 利用newInstance 创建对象
            Student student = (Student) constructor.newInstance("张三", 11);
            System.out.println(student);

    }
}

在Class类中,有一个newInstance 方法,可以利用空参直接创建一个对象

Class clazz = Class.forName("fanshe.Student");

Student stu = (Student)clazz.newInstance();

不过这个方法现在已经过时了,了解即可

// 获取一个私有的构造方法并创建对象
package fanshe;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Demo2 {

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
            // 获取字节码文件
            Class clazz = Class.forName("fanshe.Student");

            // 获取构造方法
            Constructor constructor = clazz.getConstructor(String.class, int.class);

            // 被private修饰的成员,不能直接使用
        // 如果用反射强行获取并使用,需要临时取消访问检查
        constructor.setAccessible(true);

            // 利用newInstance 创建对象
            Student student = (Student) constructor.newInstance("张三", 11);
            System.out.println(student);

    }
}

在获取到的构造方法创建对象时,如果是public,可以直接创建对象

如果是非public的,需要临时取消检查,然后再创建对象setAccessible(boolean)(暴力反射)

反射获取成员变量

  • 步骤

    • 获得class对象
    • 获得Field对象
方法名说明
Field[] getFields()返回所有公共成员变量对象的数组
Field[] getDeclaredFields()返回所有成员变量对象的数组(包括私有)
Field[] getField(String name)返回单个公共成员变量对象
Field[] getDeclaredField(String name)返回单个公共成员变量对象(包括私有)
  • 赋值或者获取值

    void set(Object obj, Object value):给指定对象的成员变量赋值

    Object get(Object obj):返回指定对象的Field的值

代码实现

package fanshe;

import java.lang.reflect.Field;

public class Demo2 {

    public static void main(String[] args) throws NoSuchFieldException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException {
            // 获取class对象
            Class clazz = Class.forName("fanshe.Student");
            // 获取Field对象
            Field field = clazz.getDeclaredField("name");
            // 赋值
                    // 创建一个对象
            Student stu = (Student)clazz.newInstance();
                    // 关闭访问检查(私有变量)
            field.setAccessible(true);
                    // 赋值
            field.set(stu, "张三");
            System.out.println(stu);
    }
}

获取Method对象

  1. 获取class对象
  2. 获取Method对象
方法名说明
Method[] getMethods()返回所有公共成员方法对象的数组,包括继承的
Method[] getDeclaredMethods()返回所有成员方法对象的数组,不包括继承的,包括私有的
Method[] getMethod(String name, Class...parameterTypes)返回单个公共成员方法对象
Method[] getDeclaredMethod(String name, Class...parameterTypes)返回单个成员方法对象(包括私有)
  1. 运行方法

    Object invoke(Object obj, Object...args):运行方法

    参数一:表示用obj对象调用该方法

    参数二:调用方法的传递的参数(如果没有就不写)

    返回值:方法的返回值(没有就不写)

代码演示

package fanshe;

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

public class Demo3 {
    public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
            // 获取class对象
            Class clazz = Class.forName("fanshe.Student");
            // 获取Method对象
            Method method = clazz.getDeclaredMethod("function", String.class, int.class);
            // 创建对象
            Student stu = (Student)clazz.newInstance();
            // 运行
            method.setAccessible(true);
            method.invoke(stu, "张三",23);
    }
}

xml

概述

  • 由万维网联盟(W3C)推出

    是Web领域最具权威和影响力的国际中立性技术标准机构

  • 可扩展的标记语言XML(标准通用标记语言下的一个子集)

    标记语言:通过标签来描述数据的一门语言(标签也称为元素)

    可扩展:标签的名字是可以自己定义的

  • 作用:

    • 用于进行存储数据和传输数据
    • 作为软件的配置文件

规则

标签规则

  • 标签由一对尖括号和合法的标识符组成
  • 标签必须成对出现
  • 特殊标签可以不成对,但是必须要有结束标记
  • 标签中可以定义属性,属性和标签名空格隔开;属性值必须用引号引起来
  • 标签需要正确的嵌套

语法规则

  • 文件后缀名为:xml
  • 文档声明必须是第一行第一列

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

    version:该属性是必须存在

    encoding:该属性不是必须的,声明打开当前xml文件的时候应该使用什么字符编码表

    standalone:该属性不是必须的,描述XML文件是否依赖其他的xml文件,取值为yes/no

  • 必须存在一个根标签,有且仅有一个
  • XML文件中可以定义注释信息
  • XML文件中可以存在特殊字符(\&lt; \&gt;......)
  • XML文件中可以存在CDATA区

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

演示

<?xml version="1.0" encoding="UTF-8"?>
<!--根标签-->
<students>
  <!--第一个学生信息-->
    <student id="1">
    <name>张三</name>
      <age>23</age>
      <info>学生 < >信息</info>
      <!--CDATA区内的内容都会原样输出,大于号和小于号等不用使用特殊字符转义-->
      <message><![CDATA[内<>容]]></message>
  </student>
  <!--第二个学生信息-->
  <student id="2">
    <name>李四</name>
      <age>24</age>
      <info></info>
  </student>
</students>

解析

  • 解析就是从xml中获取到数据
  • DOM(Document Object Model)文档对象模型:就是把文档的各个组成部分看做成对应的对象

    会把xml文件全部加载到内存。在内存中形成一个树形结构,再获取到对应的值

  • 常见的解析工具

    • JAXP:SUN公司提供的一套XML的解析的API
    • JDOM:开源组织提供了一套XML的解析的API-jdom
    • DOM4J:开源组织提供了一套XML的解析的API-dom4j(全称:Dom For Java)
    • pull:主要应用在Android手机端解析XML

DOM4J

  • 下载地址:https://dom4j.github.io/
  • 常用方法

    SAXReader saxReader = new SAXReader();:获取一个解析器对象

    Document document = saxReader.read(new File("xml文件路径")):利用解析器把xml文件加载到内存中,并返回一个文档对象

    Element rootElement = document.getRootElement() :获取到根标签

    List list = rootElement.elements() :获取调用者所有的子标签,并加入到集合,最终返回这个集合

    List list = rootElement.elements("标签名") :获取调用者所有的指定的子标签,会把这些子标签放到一个集合中并返回

    Attribute attribute = element.attribute("属性名") :获取标签对应的属性

    String id = attribute.getValue():获取对应属性的值

    Element nameElement = element.element("标签名");:获取调用者指定的子标签

    String name = nameElement.getText():获取这个标签的标签体内容

代码

package MyXml;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class Demo {

    public static void main(String[] args) throws DocumentException {
            // 获取一个解析器对象
            SAXReader saxReader = new SAXReader();
            // 利用解析器把xml文件加载到内存中
            Document document = saxReader.read(new File("src\\MyXml\\Students.xml"));
            // 获取到根标签
            Element rootElement = document.getRootElement();
            // 获取子标签
            List<Element> list = rootElement.elements("student");
            // 遍历获取每个student信息
            ArrayList<Student> s = new ArrayList();
            for(Element element : list){
                    // 获取属性
                    Attribute attribute = element.attribute("id");
                    String id = attribute.getText();
                    // 获取name
                    Element nameElement = element.element("name");
                    String name = nameElement.getText();
                    // 获取age
                    Element ageElement = element.element("age");
                    int age = Integer.parseInt(ageElement.getText());
                    Student stu = new Student(id,name,age);
                    s.add(stu);
            }
            System.out.println(s);
    }
}

DTD&schema

约束

  • 用来限定xml文件中可使用的标签以及属性
  • 分类

    • DTD
    • schema

DTD约束

步骤

  • 创建一个文件,这个文件的后缀名为.dtd
  • 看xml文件中使用了哪些元素

    <!ELEMENT>可以定义元素:<!ELEMENT persons>

  • 判断元素是简单元素还是复杂元素

    • 简单元素:没有子元素<!ELEMENT name (#PCDATA)>
    • 复杂元素:有子元素的元素<!ELEMENT person (name,age)>
  • 引入DTD

引入DTD约束的三种方法

  • 引入本地dtd:<!DOCTYPE 根标签名 SYSTEM 'DTD文件路径'>
  • 在xml文件内部引入:<!DOCTYPE 根标签名 [DTD文件内容]>
  • 引入网络dtd:<!DOCTYPE 根标签名 PUBLIC "dtd文件名称" "dtd文档的URL">

DTD语法规则

  • 定义一个元素:<!ELEMENT 元素名 元素类型>

元素类型

简单元素:

EMPTY:表示标签体为空

ANY:表示标签体可以为空也可以不为空

PCDATA:表示该标签的内容部分为字符串

复杂元素:

直接写子元素名称

多个子元素可以用","或者'|'隔开;

","表示定义子元素的顺序

"|"表示子元素只能出现任意一个

(?表示零次或多次;"+"表示一次或多次;"*"表示零次或多次;如果不写默认表示出现一次)

  • 定义一个属性:<!ATTLIST 元素名称 属性名称 属性类型 属性约束>

    属性类型:CDATA类型(普通的字符串)

    属性约束

#REQUIRED:必需的

#IMPLIED:属性不是必需的

#FIXED value:属性值是固定的

schema约束

schema和DTD的区别

  • schema约束文件也是一个xml文件,符合xml语法,后缀名为.xsd
  • 一个xml中可以引用多个schema约束文件,多个schema使用名称空间区分(名称空间类似于java包名)
  • dtd里面元素类型的取值比较单一常见的是PCDATA类型,但是在schema里面可以支持很多个数据类型
  • schema语法更加复杂
schame文件用来约束一个xml文件,因为其自身也是一个xml文件,所以同时也被别的文件约束着

步骤

  • 创建一个文件,这个文件后缀名为.xsd
  • 定义文档声明
  • schema文件的根标签为:<schema>
  • 中定义属性:

    xmlns=http://www.w3.org/2001/XMLSchema(声明这个schema文件是一个约束文件,同时也被约束)

  • 中定义属性:

    targetNamespace=唯一的url地址(指定当前这个schema文件的名称空间)

  • 中定义属性:

    elementFormDefault="qualified"(表示当前schema文件是一个质量良好的文件)

  • 通过element定义元素
  • 判断当前元素是简单元素还是复杂元素

代码实现

<? xml version="1.0" encoding="UTF-8" ?>
<schema
    xmlns="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://www.baidu.com/javase"
  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 = "int"></element>
                      </sequence>
                  </complexType>
              </element>
          </sequence>
      </complexType>
  </element>
</schema>

引入schema文件约束

  • 在根标签上定义属性

    xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"(表示当前文件被别人约束)

  • 通过xmlns引入约束文件的名称空间

    xmlns = "约束文件的名称空间"

  • 给某一个xmlns属性添加一个标识,用于区分不同的名称空间

    格式为xmlns:标识 = "名称空间地址"

    标识是可以任意的,但是一般取值都是xsi

  • 通过xsi:schemaLocation指定名称空间所对应的约束文件路径

    格式为:xsi:schemaLocation = "名称空间url 文件路径"

Schema定义属性

  • <attribute name="id" type="string" use="required"></attribute>

    use中两个选项:requried(必需的)、optional(可选的)


枚举&注解

  • 用常量表示季节的弊端

    代码不够简洁

    不同类型的数据是通过名字区分的

    不安全,由于是数字类型,就有可能使用这几个值做一些运算操作;

为了间接的表示一些固定的值,Java提供了枚举

枚举格式

  • 枚举:是指将变量的值一一列出来,变量值只限于列举出来的值的范围内

格式

public enum s{
  枚举项1,枚举项2,枚举项3;
}
// 定义一个枚举类,用来表示春、夏、秋、冬
public enum Season{
  SPRING,SUMMER,AUTUMN,WINTER;
}

枚举特点

  1. 所有枚举类都是Enum的子类
  2. 可以通过"枚举类名.枚举项名称"去访问指定的枚举项
  3. 每一个枚举项其实就是该枚举的一个对象
  4. 枚举也是一个类,也可以去定义成员变量
  5. 枚举类的第一行上必须是枚举项,最后一个枚举项后的分号是可以省略的,但是如果枚举类有其他的东西,这个分号就不能省略。建议不要省略
  6. 枚举类可以有构造器,但必须是private的,它默认的也是private的。
  7. 枚举类也可以有抽象方法,但是枚举项必须重写该方法
public enum Season{
    SPRING("春"){
       // 枚举类中有抽象方法,必须重写
        public void show(){
            System.out.println(this.name);
        }
    },
    SUMMER("夏"){
        public void show(){
            System.out.println(this.name);
        }
  
    },
    AUTUMN("秋"){
        public void show(){
            System.out.println(this.name);
        }
  
    },
    WINTER("冬"){
        public void show(){
            System.out.println(this.name);
        }
  
    };
    // 成员变量
    public String name;
    // 有参构造
    private Season(String name){
        this.name = name;
    }
    // 抽象方法
    public abstract void show();
}

枚举的方法

方法名说明
String name()获取枚举项的名称
int ordinal()返回枚举项在枚举类中的索引值
int compareTo(E o)比较两个枚举项,返回的是索引值的差值
String toString()返回枚举常量的名称
static T valueOf(Class type, String name)获取指定枚举类中的指定名称的枚举值
values()获得所有的枚举项

注解

  • 主要作用:对程序进行标注和解释
注解名说明
@Override概述子类重写父类的方法
@Deprecated概述方法过时
@SuppressWarnings压制警告
@Retention(value = RetentionPolicy.RUNTIME)表示这个注解的存活时间
  • 注释和注解

    注释:给程序员看

    注解:给编译器看(让虚拟机看到程序中的注解,注解代表程序的一些特殊功能)

  • 自定义注解

    public @interface 注解名称{
        public 属性类型 属性名 () default 默认值;        //这里只能是public,可省略
    }

    属性类型可以为基本数据类型、String、Class、注解、枚举以及以上类型的一维数组

    在使用注解的时候如果注解里面的属性没有指定默认值,那么就需要手动给出注解属性的设置值

    特殊属性value:在使用注解时如果只给value赋值,那么可以直接设置

  • isAnnotationPresent(Class<? extends Annotation> annotationClass)

    判断当前方法上是否有指定的注解

    参数:注解的字节码文件对象

    返回值:布尔结果    true存在;false不存在

元注解

  • 概述:就是描述注解的注解
元注解名说明
@Target指定了注解能在哪里使用
@Retention可以理解为保留时间(生命周期)
@Inherited表示修饰的自定义注解可以被子类继承
@Documented表示该自定义注解,会出现在API文档里面

@Target:成员变量(ElementType.FIELD),类(ElementType.TYPE),成员方法(ElementType.METHOD)

@Retention:不写默认只能存活在java文件(不能存活在class文件中),括号写上RetentionPolicy.RUNTIME就可以存活到字节码中

单元测试&日志技术

  • Junit概述:Junit是一个Java编程语言的单元测试工具。Junit是一个非常重要的测试工具

Junit特点

  • 是一个开放源代码的测试工具
  • 提供注解来识别测试方法
  • 可以让编写代码更快,并提高质量
  • 优雅简洁、简单
  • 在一个条中显示进度,如果运行良好是绿色;运行失败为 红色

基本使用

  • 将junit的jar包导入到工程中
  • 编写测试方法,该测试方法必须是公共的无参数无返回值的非静态方法
  • 在测试方法上使用@Test注解标注该方法是一个测试方法
  • 选中测试方法右键通过junit运行该方法

常用注解

注解含义
@Test表示测试该方法
@Before在测试的方法前运行
@After在测试的方法后运行

日志技术

日志:程序中的日志可以用来记录程序在运行时的点点滴滴,并可以进行永久存储

区别

输出语句日志技术
取消日志需要修改代码,灵活性比较差不需要修改代码,灵活性比较好
输出位置只能是控制台可以将日志信息写入到文件或者数据库中
多线程和业务代码处于一个线程中多线程方式记录日志,不影响业务代码的性能

体系结构

日志体系结构.png

Log4j

  • 是Apache的一个开源项目,通过Log4j,可以控制日志信息输送的目的地是控制台、文件等位置
  • 也可以控制每一条日志输出格式
  • 通过定义每一条日志信息的级别,能够更细致的控制日志的生成过程
  • 这些可以通过一个配置文件来灵活的进行配置,不需要修改应用的代码

Log4j开发流程

  • 导入log4j的相关jar包
  • 编写log4j配置文件(log4j.properties/log4j.xml)
  • 在代码中获取日志的对象

log4j自己的api(不推荐使用)

弊端:如果以后要更换日志的实现类,那么下面的代码就要跟着改

private static final Logger LOGGER = Logger.getLogger(.class字节码文件);

使用slf4j里面的api来获取日志的对象

好处:如果更换日志的实现类,下面的代码不需要更改

private static final Logger LOGGER = LoggerFactory.getLogger(clss字节码文件)

按照级别设置记录日志信息

Log4j组成

  • Loggers(记录器):日志的级别

常用级别:

DEBUG     打印基本信息

INFO     打印重要信息

WARN     打印可能出现问题的信息

ERROR     出现错误的信息,不影响程序运行

FATAL     重大错误,程序可以停止

DEBUG<INFO<WARN<ERROE<FATAL

Log4j有一个规则:只输出级别不低于设定级别的日志文件

  • Appenders(输出源):日志要输出的地方,如控制台(Console)、文件(Files)等。

    org.apache.log4j.ConsoleAppender(控制台)

    org.apache.log4j.FileAppender(文件)

log4j.appender.ca = org.apache.log4j.ConsoleAppender
log4j.appender.ca.设置1 = 值1
log4j.appender.ca.设置2 = 值2
...........
  • Layouts(布局):日志输出的格式

常用布局管理器:

org.apache.log4j.PatternLayout(可以灵活的指定布局模式)【最常用】

org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)

org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等信息)

log4j.appender.ca.layout = org.apache.log4j.PatternLayou
log4j.appender.ca.layout.设置1 = 值1
log4j.appender.ca.layout.设置2 = 值2
...........

配置文件详解

  • 配置根Logger

格式:log4j.rootLogger = 日志级别, appenderName1, appenderName2, ...

日志级别:OFF FATAL ==ERROR WARN INFO DEBUG== ALL或者自定义的级别

appenderName1:就是指定日志信息要输出到哪里。可以同时指定多个输出目的地,用逗号隔开

例如:log4j.rootLogger = INFO, ca, fa

  • 配置文件

ConsoleAppender常用的选项

ImmediateFlush = true     表示所有消息都会被立即输出,设置为false则不输出,默认为true

Target = System.err     默认值是System.out

FileAppender常用的选项

ImmediateFlush = true     表示所有消息都会立即被输出。设为false则不输出,默认值是true

Append = false     true表示将消息添加到指定文件中,原来的消息不覆盖

false则将消息覆盖指定的文件内容,默认值为true

File = D:/logs/logging.log4j     指定消息输出到logging.log4j文件中

  • 配置Layout

PatternLayout常用的选项

ConversionPattern=%m%n     设定以怎样的格式显示消息

【格式化符号说明可以查看网上的资料做一个了解】

Log4j应用

  • 使用步骤

    • 导入相关的依赖(jar)
    • 将资料中的properties配置文件复制到src目录下
    • 在代码中获取日志的对象
    • 按照级别设置记录日志信息

本系列文章导读:【JavaSE】文章导读

JavaSE部分完结

如有问题,欢迎指正(评论区留言即可)

发表评论时请填写正确邮箱,以便于接收通知【推荐QQ邮箱】


END

本文作者: 文章标题:【JavaSE】基础加强
本文地址:https://www.hellocode.top/archives/34/
版权说明:若无注明,本文皆HelloCode原创,转载请保留文章出处。
最后修改:2022 年 04 月 16 日
如果觉得我的文章对你有用,请随意赞赏