学习内容(2020 11/24)
反射、JUnit单元测试的使用、xml文件的解析
一、反射
JAVA反射是指对于任意一个类,都可以获取这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Class类:这个类用于操纵(反向解析)一个类的属性,方法,构造器等。对于一个类,Class只要获取类名,那么它便可知道你所有的属性,不止属性,甚至方法上的注解等等,都可以获取。
面试题:简述java中的反射机制
反射其实就是通过指定包名及类名,找到类中的属性、方法和构造器,然后进行对象的构建
- 反射机制获取类有三种方法:
//第一种方式:
Class c1 = Class.forName(“类名”);
//第二种方式:
//java中每个类型都有class 属性.
Class c2 = 类名.class;
//第三种方式:
//java语言中任何一个java对象都有getClass 方法
User e = new User ();
Class c3 = e.getClass();
package reflex;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import beans.Item;
public class ReflexDemo {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
method();
}
public static void method() throws ClassNotFoundException, NoSuchMethodException, SecurityException {
Class cls1 = Class.forName("beans.Item");
// Method[] me = cls1.getMethods();
// for(Method me1 : me) {
// System.out.println(me1);
// }
Method me2 = cls1.getMethod("setPirce", double.class);
System.out.println(me2);
}
/***
* 前两种方法不常用,使用的前提是类中有对应的java文件
* 通常情况下在使用第三方jar包时,能知道的仅仅是通过Build path添加到功能中的class文件的路径和名称
*
* 包名+文件名
* 使用Class类中提供的方法:forName(String path)
* @throws ClassNotFoundException
* @throws SecurityException
* @throws
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static void reflexMethod3() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class cls1 = Class.forName("beans.Item");
// Constructor[] cons = cls1.getConstructors();//获取所有公共的构造器
// //Constructor[] cons = cls1.getDeclaredConstructors();//获取所有构造器
// for(int i=0;i<cons.length;i++) {
// //System.out.println(cons[i]+" "+cons[i].getParameterCount());
// if(cons[i].getParameterCount()==2) {
// //他要创建带有具体参数的对象
// Item item =(Item)cons[i].newInstance("adhad",12323);
// System.out.println(item);
// }
// }
try {
Constructor con=cls1.getConstructor(String.class,int.class);
Item item =(Item)con.newInstance("adhad",12323);
System.out.println(item);
} catch (NoSuchMethodException e) {
System.out.println("没有该类型");
} catch (SecurityException e) {
e.printStackTrace();
}
}
/**
* 返回Class对象的方式二:
* 每一个对象都具备一个.class属性
*/
public static void reflexMethod2() {
Class cls1 = User.class;
Class cls2 = User.class;
System.out.println(cls1==cls2);//true
Class cls3 = int.class;
Class cls4 = Integer.class;
System.out.println(cls3==cls4);//false
}
/**
* 返回Class对象的方式一:getclass()
* 每一个引用数据类型都有一个getclass()方法,此方法返回的就是该类的class对象
*/
public static void reflexMethod() {
User user1 = new User();
Class cls1 = user1.getClass();
User user2 = new User();
Class cls2= user2.getClass();
//同一个类只有一个class文件,而这个class文件所对应的类型是Class
System.out.println(cls1 == cls2);//true
}
}
class User{
private int age;
private String neme;
public User() {}
public User(int age, String neme) {
super();
this.age = age;
this.neme = neme;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getNeme() {
return neme;
}
public void setNeme(String neme) {
this.neme = neme;
}
@Override
public String toString() {
return "User [age=" + age + ", neme=" + neme + "]";
}
}
二、JUnit单元测试的使用
我们可以在项目中关联JUnit的jar包,然后在所需要的进行测试的方法上加上注解@Tset即可使用
在扩展中了解到另一种使用方式(转载如下链接)
https://blog.youkuaiyun.com/wangpeng047/article/details/9627527
实际测试:
package test;
import org.junit.Test;
/**
* 步骤
* 1.关联JUnit的jar包(4)
* 2.测试使用@Test注解
*
*/
public class JUnitTest {
@Test
public void method() {
System.out.println("asdasd");
}
}
三、xml文件的解析
如何解析xml文件:
-
DOM:优点是直观好理解,缺点是DOM解析需要一次性的解析整个xml文件,容易出现内存溢出
-
SAX:采用事件驱动,内存消耗小,无法同时访问多处不同的数据
-
DOM4J:是JDOM的智能分支,灵活好用,开源
-
JDOM:大量使用了Collections类,贴合java的API
package xml;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.dom4j.Attribute;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import beans.Item;
public class DOMParse {
public static void main(String[] args) {
}
@Test
public void domParse() throws ParserConfigurationException, FileNotFoundException, SAXException, IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//先创建一个工厂对象--DocumentBuilderFactory,用于创建生产对象的机器对象--DocumentBuilder
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//创建DocumentBuilder对象用于创建Document对象
DocumentBuilder builder = factory.newDocumentBuilder();
//创建Document对象
Document document = builder.parse(new FileInputStream("src/item.xml"));
//查找文件中的标签
NodeList nodelist = document.getElementsByTagName("bean");
//遍历节点集合
for(int i=0;i<nodelist.getLength();i++) {
//获取当前遍历的Node节点
Element element =(Element)nodelist.item(i);
String idVal = element.getAttribute("id");
String claVal = element.getAttribute("class");
System.out.println(idVal+" "+claVal);
//通过反射进行解析
Class cls = Class.forName(claVal);
Constructor cons = cls.getConstructor(String.class);
//构建对象
Item item = (Item)cons.newInstance("被子");
System.out.println(item);
}
}
/**
* dom4j中也需要使用Document对象
* 但是一个java文件只能导一个包,当有多个时,可以直接在类的前面加上包名
* @throws DocumentException
* @throws FileNotFoundException
*/
@Test
public void dom4jParse() throws FileNotFoundException, DocumentException {
SAXReader reader = new SAXReader();
//解析xml文件
org.dom4j.Document document = reader.read(new FileInputStream("src/item.xml"));
//获取文档根结构
org.dom4j.Element rootelement = document.getRootElement();
//根据根节点去查找其下面所有的子节点
List<org.dom4j.Element> elementList = rootelement.elements();
//遍历节点集合
for(int i=0; i<elementList.size();i++) {
//获取当前节点对象
org.dom4j.Element element= elementList.get(i);
//将节点中所有属性放入一个List<Attribute>
List<Attribute> attrList = element.attributes();
//遍历
for(Attribute attr : attrList) {
String keyname = attr.getName();
String keyVal = attr.getValue();
System.out.println(keyname+" "+keyVal);
}
}
}
}