目录
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能成为java语言的反射机制。
简单的说:一个类有多个组成部分,例如:成员变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分。
JAVA反射机制主要提供以下功能:
- 在运行时判断任意一个对象所属的类;
- 在运行时构造任意一个类的对象;
- 在运行时判断任意一个类所具有的成员变量和方法;
- 在运行时调用任意一个对象的方法;
- 生产动态代理。
一、JAVA反射的API
建一个Ainmal类
public class Animal {
public String Name;
private int age;
public void eat(){
System.out.println(123);
}
public void eat(String food){
System.out.println(food);
}
public String eat(String food,int age){
return food + age;
}
public void list1(){
List list = new ArrayList();
}
}
1、获取类的方法
public static void main(String[] args) {
// 1、通过类来获取
Class<Animal> animalClass = Animal.class;
// 2、通过全类名来获取
try {
Class animalClass2 = Class.forName("com.xinzhi.Animal");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 3、使用对象来获取
Animal animal = new Animal();
Class<? extends Animal> aClass = animal.getClass();
String name = animalClass.getName();
System.out.println(name);
}
2、获取字段并操作
@Test
public void optField(){
Animal animal = new Animal();
Class<Animal> animalClass3 = Animal.class;
// 只获取公共的字段
Field[] fields = animalClass3.getFields();
for (Field field : fields) {
System.out.println(field.getName());
try {
field.set(animal,"5");
System.out.println( field.get(animal));
} catch (IllegalAccessException e) {
System.out.println("name必须是字符串");
e.printStackTrace();
}
}
System.out.println("-----");
try {
// 获取所有的字段
Field declaredFields = animalClass3.getDeclaredField("age");
// 在其他类中设置私有属性字段必须加下面这行代码,否则报错
declaredFields.setAccessible(true);
declaredFields.set(animal,12);
System.out.println(declaredFields.get(animal));
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
3、获取方法并操作
@Test
public void optMethod(){
Animal animal = new Animal();
Class<Animal> animalClass = Animal.class;
try {
Method eat = animalClass.getMethod("eat",String.class,int.class);
Object food = eat.invoke(animal, "骨头", 23);
System.out.println(food);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
4、构造函数
@Test
public void optConstructor(){
Class<Animal> animalClass = Animal.class;
try {
Constructor<Animal> constructor = animalClass.getConstructor();
Animal animal = constructor.newInstance();
animal.eat();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
5、拿到xml文件,并把它写入txt
(1)新建class.xml
<class name="开发六部">
<student>
<name>张三</name>
<age>12</age>
<gender>男</gender>
</student>
<student>
<name>李四</name>
<age>13</age>
<gender>男</gender>
</student>
<student>
<name>王五</name>
<age>14</age>
<gender>男</gender>
</student>
</class>
(2)新建Clazz类
public class Clazz {
private String name;
private List<Student> students;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
@Override
public String toString() {
return "Clazz{" +
"name='" + name + '\'' +
", students=" + students +
'}';
}
}
(3)新建student类,对应xml文件
public class Student {
private String name;
private int age;
private String gender;
public Student(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public Student(){}
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;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
(4)测试类,把xml的内容写入TXT中
public class Test {
public static void main(String[] args) {
// Student s1 = new Student("张三",12,"男");
// Student s2 = new Student("李四",13,"男");
// Student s3 = new Student("王五",14,"女");
// List<Student> students = Arrays.asList(s1, s2, s3);
//
// Clazz clazz = new Clazz();
// clazz.setName("开发六部");
// clazz.setStudents(students);
//
// System.out.println(students);
Clazz readxml = readxml();
System.out.println(readxml);
}
public static Clazz readxml(){
Clazz clazz = new Clazz();
List<Student> list = new ArrayList<>();
SAXReader reader = new SAXReader();
try {
// 读xml文件
org.dom4j.Document document = reader.read(Test.class.getClassLoader().getResourceAsStream("conf/class.xml"));
// 获取节点
Element root = document.getRootElement();
// 写xml文件
XMLWriter xmlWriter = null;
xmlWriter = new XMLWriter(new FileOutputStream("D://user.txt"));
xmlWriter.write(document);
xmlWriter.flush();
xmlWriter.close();
// 拿到class的name开发六部
clazz.setName(root.attribute("name").getValue());
List<Element> elements = root.elements();
for (Element element : elements) {
List<Element> elements1 = element.elements();
Student student = new Student();
for (Element element1 : elements1) {
Class<Student> studentClass = Student.class;
Field field = studentClass.getDeclaredField(element1.getName());
field.setAccessible(true);
if (field.getType() == String.class) {
field.set(student, element1.getData());
}else if(field.getType() == int.class){
field.set(student,Integer.parseInt(element1.getData().toString()));
}
}
list.add(student);
}
clazz.setStudents(list);
} catch (DocumentException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return clazz;
}
}
二、JAVA Properties类的使用详解
1、Properties的使用
(1)新建Source接口
public interface Source {
void select();
}
(2)新建Mysql类,实现Source
public class Mysql implements Source{
@Override
public void select(){
System.out.println("从mysql中查找");
}
}
(3)新建SqlServer类,实现Source
public class SqlServer implements Source{
@Override
public void select(){
System.out.println("从sqlserver里查找数据");
}
}
(4)新建conf.properties,修改最后的类名,就能确定从哪查找
target = com.xinzhi.sql.Mysql
(5)测试类,properties的使用
public class Test {
public static void main(String[] args) throws Exception{
Properties properties = new Properties();
InputStream inputStream = new FileInputStream("D:\\IDEA\\javateach\\jdbc-1\\jdbc\\src\\conf.properties");
properties.load(inputStream);
String target = properties.getProperty("target");
Source source = (Source) Class.forName(target).newInstance();
source.select();
}
}