类加载器
将.class文件(存储的物理文件)加载到内存中
加载时机:用到就加载,不用不加载
加载
通过全类名获取到类,用流将其加载至内存,创建一个class对象(用来存储成员信息)
链接(验证,准备,解析)
1.验证:确保Class文件字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身安全
2.准备:负责为类的类变量(被static修饰的变量)分配内存,并设置默认初始化值
3.解析:符号引用替换为直接引用
初始化
初始化类变量和其他资源
分类
Bootstrap class loader:虚拟机的内置类加载器(最顶层)
Platform class loader:平台类加载器
System class loader:系统类加载器
双亲委派模型:
Bootstrap class loader -> Platform class loader -> System class loader
System class loader -> Platform class loader -> Bootstrap class loader
常用方法
getSystemClassLoader()
getResourceAsStream()
// 获取系统类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
// 加载文件
InputStream stream = systemClassLoader.getResourceAsStream("prop.properties");
Properties p = new Properties();
p.load(stream);
System.out.println(p);
stream.close();
反射
正常情况通过类 new 对象调用属性方法
反射是把类(Class)当做对象,通过类对象调用里面属性(Field)方法(Method)和构造(Constructor)
获取Class对象
//Class中静态方法 参数是全类名
Class name = Class.forName("com.ithema.day16.Student");
System.out.println(name);
//通过class属性
Class studentClass = Student.class;
System.out.println(studentClass);
//用对象的getClass方法
Student student = new Student();
Class aClass = student.getClass();
System.out.println(aClass);
获取Constructor对象
Constructor<?>[] getConstructors() 返回所有公共构造方法对象的数组
Constructor<?>[] getDeclaredConstructors() 返回所有构造方法对象的数组
Constructor<T> getConstructor(Class<?>... parameterTypes) 返回单个公共构造方法对象
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 返回单个构造方法对象
根据Constructor创建对象
Class aClass = Class.forName("com.ithema.day16.Student");
Constructor constructor = aClass.getConstructor(String.class, int.class);
Student student = (Student) constructor.newInstance("张三", 23);
System.out.println(student);
获取Field对象
Field[] getFields() 返回所有公共成员变量对象的数组
Field[] getDeclaredFields() 返回所有成员变量对象的数组
Field getField(String name) 返回单个公共成员变量对象
Field getDeclaredField(String name) 返回单个成员变量对象
赋值取值
Class<?> aClass = Class.forName("com.ithema.day16.Student");
Field field = aClass.getField("name");
//有了对象才可以给指定对象进行赋值
Student student = (Student) aClass.newInstance();
field.set(student,"张三");//赋值
System.out.println(student);
Field field2 = aClass.getField("age");
field2.setAccessible(true);// 访问私有需要取消检查
Student student2 = (Student) aClass.newInstance();
Object o = field2.get(student2);//取值
System.out.println(o);
获取Method对象
Method[] getMethods() 返回所有公共成员方法对象的数组,包括继承的
Method[] getDeclaredMethods() 返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name, Class<?>... parameterTypes) 返回单个公共成员方法对象
Method getDeclaredMethod(String name, Class<?>... parameterTypes) 返回单个成员方法对象
运行方法
Class<?> aClass = Class.forName("com.ithema.day16.Student");
Method run = aClass.getMethod("run");
//创建一个Student对象,当做方法的调用者
Student student = (Student)aClass.newInstance();
//运行方法
run.invoke(student);
练习
反射破解泛型
1.创建ArrayList集合对象,泛型设置为String
2.通过反射往集合中添加int,double等数据
ArrayList<String> list = new ArrayList<>();
Class aClass = list.getClass();
Method add = aClass.getMethod("add", Object.class);
ArrayList list1 = (ArrayList) aClass.newInstance();
add.invoke(list1,123);
add.invoke(list1,12.3);
System.out.println(list1);
XML
是一种可扩展的标记语言
作用
-
用于进行存储数据和传输数据
-
作为软件的配置文件
作为配置文件的优势
-
可读性好
-
可维护性高
文档声明必须是第一行第一列
语法
<?xml version="1.0" encoding="UTF-8" standalone="yes”?> version:该属性是必须存在的 encoding:该属性不是必须的
-
必须存在一个根标签,有且只能有一个
-
XML文件中可以定义注释信息
-
XML文件中可以存在以下特殊字符
< < 小于 > > 大于 & & 和号 ' ' 单引号 " " 引号
-
XML文件中可以存在CDATA区
<![CDATA[ …内容… ]]>
解析
DOM文档对象模型:就是把文档的各个组成部分看做成对应的对象。
会把xml文件全部加载到内存,在内存中形成一个树形结构,再获取对应的值
Document对象:整个xml文档
Element对象:所有标签
Attribute对象:所有属性
Text对象:所有文本内容
标签,属性,内容统称Node对象
DTD约束和schema约束,用于约束xml文件
枚举
为了间接的表示一些固定的值,java提供了枚举
特点
-
所有枚举类都是Enum的子类
-
我们可以通过"枚举类名.枚举项名称"去访问指定的枚举项
-
每一个枚举项其实就是该枚举的一个对象
-
枚举也是一个类,也可以去定义成员变量
-
枚举类的第一行上必须是枚举项,最后一个枚举项后的分号是可以省略的,但是如果枚举类有其他的东西,这个分号就不能省略。建议不要省略
-
枚举类可以有构造器,但必须是private的,它默认的也是private的。
枚举项的用法比较特殊:枚举("");
-
枚举类也可以有抽象方法,但是枚举项必须重写该方法
寒假快乐交换机
常用方法
String name() 获取枚举项的名称
int ordinal() 返回枚举项在枚举类中的索引值
int compareTo(E o) 比较两个枚举项,返回的是索引值的差值
String toString() 返回枚举常量的名称
static <T> T valueOf(Class<T> type,String name) 获取指定枚举类中的指定名称的枚举值
values() 获得所有的枚举项
注解
概述
对我们的程序进行标注和解释
注释: 给程序员看的
注解: 给编译器看的
使用注解进行配置配置的优势
代码更加简洁,方便代码更加简洁,方便
格式格式
public @interface 注解名称 {
public 属性类型 属性名() default 默认值 ;
}
元注解
@Target 指定了注解能在哪里使用
@Retention 可以理解为保留时间(生命周期)
@Inherited 表示修饰的自定义注解可以被子类继承
@Documented 表示该自定义注解,会出现在API文档里面。
单元测试
导入junit-4.9.jar
@Before
public void show1(){
System.out.println("show1........");
}
@Test
public void show2(){
System.out.println("show2........");
}
@After
public void show3(){
System.out.println("show3........");
}
日志技术
//导入jar包和配置文件
private static final Logger LOGGER = LoggerFactory.getLogger(text02.class);
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.next();
try {
int i = Integer.parseInt(s);
System.out.println("类型转换成功:" + i);
} catch (NumberFormatException e) {
LOGGER.info("类型转换失败");
}
}