Java XML和反射详解

您所在的位置:网站首页 java反射的理解 Java XML和反射详解

Java XML和反射详解

2024-06-16 18:45| 来源: 网络整理| 查看: 265

什么是 XML?

XML 指可扩展标记语言(EXtensible Markup Language)。 XML 是一种很像HTML的标记语言。 XML的设计宗旨是传输数据,而不是显示数据。 XML 标签没有被预定义。您需要自行定义标签。 XML 被设计为具有自我描述性。 XML 是 W3C的推荐标准。

XML 和 HTML 之间的差异

XML 不是 HTML 的替代。。

XML 和 HTML 为不同的目的而设计:

XML 被设计用来传输和存储数据,其焦点是数据的内容。 HTML 被设计用来显示数据,其焦点是数据的外观。 HTML 旨在显示信息,而 XML 旨在传输信息。

一、什么是反射:

1)Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。

(2)Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程序在运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载到JVM。通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译期知道运行的对象是谁。

二、反射的原理

下图是类的正常加载过程、反射原理与class对象:

Class对象的由来是将class文件读入内存,并为之创建一个Class对象。

在这里插入图片描述

三、反射的优缺点:

1、优点:在运行时获得类的各种内容,进行反编译,对于Java这种先编译再运行的语言,能够让我们很方便的创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代码的链接,更加容易实现面向对象。

2、缺点:(1)反射会消耗一定的系统资源,因此,如果不需要动态地创建一个对象,那么就不需要用反射;

(2)反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。

四、反射的用途:

1、反编译:.class–>.java

2、通过反射机制访问java对象的属性,方法,构造方法等

3、当我们在使用IDE,比如Ecplise时,当我们输入一个对象或者类,并想调用他的属性和方法是,一按点号,编译器就会自动列出他的属性或者方法,这里就是用到反射。

4、反射最重要的用途就是开发各种通用框架。比如很多框架(Spring)都是配置化的(比如通过XML文件配置Bean),为了保证框架的通用性,他们可能需要根据配置文件加载不同的类或者对象,调用不同的方法,这个时候就必须使用到反射了,运行时动态加载需要的加载的对象。

五、反射机制常用的类:

Java.lang.Class;

Java.lang.reflect.Constructor;

Java.lang.reflect.Field;

Java.lang.reflect.Method;

Java.lang.reflect.Modifier;

1、获得Class:主要有三种方法:

(1)Object–>getClass

(2)任何数据类型(包括基本的数据类型)都有一个“静态”的class属性

(3)通过class类的静态方法:forName(String className)(最常用)

@Test //获取Class --范围:所有的字节码文件 public void test1() throws ClassNotFoundException { //方式一,通过类名 Class c = Dog.class; //Dog.java 编译后的字节码 Class c1 = Book.class; //Book.java编译后的字节码文件 // 方式二--通过对象 Class c3 = new Dog().getClass(); // 方式三--通过类路径 Class c4 = Class.forName("demo.Book"); System.out.println(c4); System.out.println(c3); }

2.创建实例:通过反射来生成对象主要有两种方法:

(1)使用Class对象的newInstance()方法来创建Class对象对应类的实例。

//1.管理无参构造 @Test public void test2() throws Exception { //1.获取到某个类的字节码文件对象,即class的对象 Class c = Dog.class; // 2.帮你调用无参构造 Dog dog = c.newInstance(); System.out.println(dog); }

(2)先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建对象,这种方法可以用指定的构造器构造类的实例。

//2.管理有参构造 @Test public void test3() throws Exception { // 1.获取到某个类的字节码文件对象,即class的对象 Class c = Dog.class; // 2.获取有参构造的管理对象--2个参数的那个 Constructor con = c.getDeclaredConstructor(String.class); // 3.帮助Dog类调用有参构造 Dog dog = con.newInstance("旺财"); System.out.println(dog); }

3、通过反射获取构造方法并使用:

(1)批量获取的方法: public Constructor[] getConstructors():所有"公有的"构造方法 public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)

(2)单个获取的方法,并调用: public Constructor getConstructor(Class… parameterTypes):获取单个的"公有的"构造方法: public Constructor getDeclaredConstructor(Class… parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;

(3) 调用构造方法:

Constructor–>newInstance(Object… initargs)

newInstance是 Constructor类的方法(管理构造函数的类)

//3.管理属性 @Test public void test4() throws Exception { //1.获取到某个类的字节码文件对象,即Class的对象 Class c = Dog.class; //2.获取某个属性的管理对象 Field f = c.getDeclaredField("name"); //先创建一个狗狗对象 Dog dog = c.newInstance(); f.setAccessible(true); //开启私有属性操作权限 //3.帮助dog给name属性赋值 f.set(dog, "来福"); System.out.println(dog); } //4.管理方法 @Test public void test5() throws Exception { //1.获取到某个类的字节码文件对象,即Class的对象 Class c = Dog.class; //2.获取某个方法setAge(int age)的管理对象 Method m = c.getDeclaredMethod("setAge", int.class); //先创建一个狗狗对象 Dog dog = c.newInstance(); //3.帮助dog给调用setAge方法 m.invoke(dog, 3); System.out.println(dog); //管理toString方法 Method m2 = c.getDeclaredMethod("toString"); System.out.println(m2.invoke(dog)); } 六、反射结合泛型案例

将一个map中的数据转存到一个实体类对象中。

@Test//案例一:将一个map中的数据转存到一个实体类对象中。 public void test5() throws Exception { HashMap map = new HashMap(); map.put("name","旺财"); map.put("age",3); Dog dog = getObject(map, Dog.class); System.out.println(dog); } public T getObject(Map map, Class c) throws Exception { T t = c.newInstance(); //1.拆开map Set entries = map.entrySet(); for (Map.Entry entry : entries) { String key = entry.getKey(); //2.将map中的值存入T这个类的对象属性中 Field f = c.getDeclaredField(key); f.setAccessible(true); f.set(t,entry.getValue()); } return t; } 七、xml和反射综合案例

宠物管理系统

1.预先定义好父类:动物类,子类:狗狗类,企鹅类,大象类, 2.在xml文件中配置各个宠物类的全路径名 3.编写一个宠物领养方法,根据用户输入的宠物名称,从xml读取相应的类路径,使用反射构建宠物对象,并返回。

注意:使用父类作为方法返回值,字符串作为参数。

旺财 reflect.pet.Dog 皮皮 reflect.pet.Penguin 肉肉 reflect.pet.Elephant @Test public void test1() throws Exception { Scanner sc=new Scanner(System.in); System.out.println("请选择您要领养的宠物:狗狗,企鹅,大象"); String name = sc.next(); Animal animal = getAnimal(name); System.out.println(animal); } public Animal getAnimal(String name) throws Exception { // 1.创建解析器 SAXReader reader = new SAXReader(); // 解析xml文档,得到document对象 Document document = reader.read("src/reflect1/pet/pet.xml"); // 根据document对象获取根节点 Element root = document.getRootElement(); // 查找根节点下的子节点 element() elements() Element animal = root.element(name); String className = animal.element("class").getText(); //2.使用反射创建对象 return (Animal) Class.forName(className).newInstance(); }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3