反射
概念:反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有的属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息和动态的获取对象的方法称为java语言的反射机制。使用的是Class类中的方法,因为解析一个类中的所有需要它的字节码文件。
(自己的理解:一个类中包括(属性,方法,构造器),利用 反射技术就可以将每一部分都i映射成一个对象。)
- 实现了java对象的动态的创建(获取类对象),
- 反射的效率比传统的创建对象效率低;
- 影响程序的性能
- 传统的创建静态对象 :例如: Person person = new Person();
类对象和类的对象的区别
类对象:通过反射一个类之后就是类对象
类的对象:就是通过new一个类的实例。
反射的三种实现方法
//反射的第一种
Class aClass = Class.forName("com.yue.test.Person");
//反射的第二种(适用于底层是反射机制的时候)
Class cla = Person.class;
//反射的第三种(适用于底层是反射机制的时候)
Class clas = new Person().getClass();
//一个类只有一个类对象
反射操作属性
Class cla = Class.forName("com.yue.test.Person");
//获取类及其父类中的所有的公共字段
Field[] fields = cla.getFields();
for(Field f:fields){
System.out.println("获取属性的名字"+f.getName());
System.out.println("获取属性的修饰符"+f.getModifiers());
System.out.println("获取属性的类型"+f.getType());//获取的是类型的Class的对象
}
//获取类中的所有的声明字段
Field[] declaredFields = cla.getDeclaredFields();
for(Field f:declaredFields){
System.out.println("获取属性的名字"+ f.getName());
System.out.println("获取属性的修饰符"+f.getModifiers());
}
//获取指定的公共字段
Field name = cla.getField("name");
System.out.println(name.getName());
//获取父类中的字段
Field name1 = cla.getSuperclass().getField("name");
System.out.println(name1.getName());
Class aClass = Class.forName("com.yue.test.Person");
//操作静态字段
Field field1 = aClass.getField("sex");
field1.set(null,"女");
System.out.println(field1.get(null));
//操作非静态字段
Field field2 = aClass.getField("name");
Object o = aClass.newInstance();
field2.set(o,"李四");
//newInstance表示创建该Class对象所表示类的一个实例。
System.out.println(field2.get(o));
//传统的创建对象中(创建完对象之后在操作属性)
//例如:将李四的蛋糕给我
//反射中(先声明属性,在声明对象)
//例如:将蛋糕给我,李四的。
//暴力反射获取私有属性
Field field = aClass.getDeclaredField("number");
field.setAccessible(true);
System.out.println(field.get(o));
}
反射中操作方法
Class cla = Class.forName("com.yue.test.Person");
//获取子类和父类中的公共方法
Method[] methods = cla.getMethods();
for(Method m: methods){
System.out.println(m.getModifiers());
System.out.println(m.getName());
}
System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
//获取类中的声明的方法
Method[] declaredMethods = cla.getDeclaredMethods();
for(Method m:declaredMethods){
System.out.println(m.getName());
}
System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
//获取类及父类中的指定公共方法
Method method = cla.getMethod("hello1", String.class, String.class);
System.out.println(method.getName());
//获取类中声明的方法
Method method1 = cla.getDeclaredMethod("hello2", int.class);
System.out.println(method1.getName());
//调用静态方法
Method hello3 = cla.getDeclaredMethod("hello3", int.class);
hello3.invoke(null,20);
//调用非静态方法
Method hello1 = cla.getDeclaredMethod("hello1", String.class, String.class);
hello1.invoke(cla.newInstance(),"女","好人");
}
日志
使用log4j进行日志的管理;
特点:日志可以单独保存在文件中;
可以完整的显示在控制台;
日志的级别很清晰;
日志的格式可以自己设置;
日志级别
fatal:严重级别
error:错误
warn:警告
info:信息
debug:验证错误的信息
log4j的配置文件
它的配置文件放在src下面,命名是:log4j.properites;
# Set root category priority to INFO and its only appender to CONSOLE.
##全局定义级别
log4j.rootCategory=INFO, CONSOLE
#log4j.rootCategory=INFO, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
##定义包,类,方法名的级别
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
##定义控制台输出的格式化
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=INFO
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=- %m%n
# LOGFILE is set to be a File appender using a PatternLayout.
##保存在系统文件中的log的信息
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.Threshold=INFO
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
日志的使用
package com.yue.log4j;
import org.apache.log4j.Logger;
public class logTest {
//在这个类中使用log4j,需要配置文件
private static Logger logger = Logger.getLogger(logTest.class);
}