Java-反射和XML.

第一节:反射(Reflection)

2.1 为什么使用反射

需求:
    我公司定义了一组接口,然后第三方公司按照我公司的接口实现了一套功能,然后交给我们,但是我们公司的项目已经结束,如何实现动态加载第三方公司提供的功能。

2.2 什么是反射

反射就是把Java类中的各种成分映射成一个个的Java对象。例如,一个类有:成员变量,方法,构造方法,包等等信息,利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个对象。

2.3 反射常用类

  • Class类—可获取类和类的成员信息

  • Field类—可访问类的属性

  • Method类—可调用类的方法

  • Constructor类—可调用类的构造方法

2.4 使用反射的基本步骤

1.导入java.lang.reflect.*

2.获得需要操作的类的Java.lang.Class对象

3.调用Class的方法获取Field、Method等对象

4.使用反射API进行操作(设置属性﹑调用方法)

 

第二节:Class类

2.1 Class类是反射机制的起源和入口

  • 每个类都有自己的Class对象

  • 提供了获取类信息的相关方法

  • Class类继承自Object类

 

2.2 Class类存放类的结构信息

  • 类名

  • 父类﹑接口

  • 方法﹑构造方法﹑属性

  • 注释

 

2.3 获取 Class对象的方式

第一种方式

//方法1:对象.getClass()
Student stu=new Student();
Class clazz=stu.getClass();

第二种方式

//方法2:类.class
clazz= Student.class;
clazz=String.class;

第三种方式(推荐)

//方法3:Class.forName()
clazz=Class.forName("java.lang.String");
clazz=Class.forName("java.util.Date");

2.4 获取类的其他结构信息

Class clazz = Class.forName("java.lang.Object");
Field fields[ ] = clazz.getDeclaredFields();//获取Field 对象 
Method methods[] = clazz.getDeclaredMethods();//获取Method 对象 
Constructor constructors[] = clazz.getDeclaredConstructors();//获取Constructor对象 

示例:

public class Person {
    //成员变量
    private String name;
    private int age;
    private String gender;
    //构造方法
    public Person() {
    }

    public Person(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    //方法
    //无参无返回值
    public void show(){
        System.out.println("姓名:"+name+" 年龄:"+age+" 性别:"+gender);
    }
    //有参无返回值
    public void show(String address){
        System.out.println("姓名:"+name+" 年龄:"+age+" 性别:"+gender+" 地址:"+address);
    }
    //带返回值的方法
    public String getInfo(){
        return "信息:"+name+"  "+age+"  "+gender;
    }

    //静态方法
    public static void print(){
        System.out.println("这是一个静态方法");
    }

    //私有方法
    private void show(String address,String email){
        System.out.println("地址:"+address+"  邮箱:"+email);
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}

使用反射获取Person类中的信息:

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Demo {
    public static void main(String[] args)throws Exception {
          // getClazz();
           //getConstructor();
          //getMethed();
        getField();

    }

    //获取类的类对象
    public static void getClazz()throws Exception{
        //使用class属性获
        Class clazz1 = Person.class;
        System.out.println(clazz1.hashCode());
        //使用getClass
           Person person=new Person();
        Class clazz2 = person.getClass();
        System.out.println(clazz2.hashCode());
        //使用 Class.forName方法   耦合性低 不依赖于具体的类 可编译通过
      Class clazz3=Class.forName("com.vince.practice04.Fanshe.fanshe01.Person");
        System.out.println(clazz3.hashCode());
    }

      public static void getConstructor()throws Exception{
       Class clazz= Class.forName("com.vince.practice04.Fanshe.fanshe01.Person");
       //获取构造方法
          Constructor[] constructors = clazz.getConstructors();
            for (Constructor constructor : constructors) {
                System.out.println(constructor);
               }


          Constructor constructor = clazz.getConstructor(); //获取单个无参

          //获取带参
          Constructor constructor1 = clazz.getConstructor(String.class, int.class, String.class);


          //创建对象
          System.out.println("-----------------------");
          Object o = constructor.newInstance();
          System.out.println(o);
          Object o1 = constructor1.newInstance("zhagnsan ", 23, "nan");
          System.out.println(o1);

      }

      //获取方法
    public static void getMethed()throws Exception{
        Class clazz = Class.forName("com.vince.practice04.Fanshe.fanshe01.Person");
       /*   //
        Method[] methods = clazz.getMethods();  // 获取类自己的所有公共方法  继承D的公开方法
        for (Method method : methods) {
            System.out.println(method);
        }
             clazz.getDeclaredMethods    // 获取类自己的公开方法和非公开的方法

           */

       //  获取带参方法
        Constructor constructor1 = clazz.getConstructor(String.class, int.class, String.class);
        Object zhangsan1 = constructor1.newInstance("张三",13,"男");
        Method method = clazz.getMethod("show", String.class);
           method.invoke(zhangsan1,"北京");

          System.out.println("-------------带返回值的方法---------------");
        Method getInfo = clazz.getMethod("getInfo");
        Object value = getInfo.invoke(zhangsan1);
        System.out.println(value);
        System.out.println("----------获取私有方法--------------");
        //获取私有方法
        Constructor constructor = clazz.getConstructor(String.class, int.class, String.class);
        Object zhangsan = constructor.newInstance("张三",13,"男");
        Method method1 = clazz.getDeclaredMethod("show", String.class, String.class);

        method1.setAccessible(true);  // 设置访问权限无效。
        method1.invoke(zhangsan,"北京","[email protected]");
        System.out.println("------------获取静态方法------------");
        Method print = clazz.getMethod("print");
          print.invoke(null);


    }


      //获取字段。
    public static void getField()throws Exception{
        Class clazz = Class.forName("com.vince.practice04.Fanshe.fanshe01.Person");

        Field[] fields = clazz.getDeclaredFields();  //获取多个字段
        for (Field field : fields) {
            System.out.println(field);
        }

        System.out.println("------------获取单个字段--------------");
        Field name = clazz.getDeclaredField("name");

        //创建对象
        Object lixin = clazz.newInstance();

        //赋值
        name.setAccessible(true);   //设置访问权限无效
            name.set(lixin, "李欣");
            //获取
        Object  object = name.get(lixin);
        System.out.println(object);


    }

}

 

第三节:反射技术的优点和缺点

优点:

1.提高了Java程序的灵活性和扩展性,降低了耦合性,提高自适应能力

2.允许程序创建和控制任何类的对象,无需提前硬编码目标类

缺点:

1.性能问题

2.代码维护问题

 

第四节:注解

什么是注解

Annotation其实就是代码里的特殊标记, 它用于替代配置文件,也就是说,传统方式通过配置文件告诉类如何运行,有了注解技术后,开发人员可以通过注解告诉类如何运行。在Java技术里注解的典型应用是:可以通过反射技术去得到类里面的注解,以决定怎么去运行类。

三个基本的 Annotation:

@Override:限定重写父类方法, 该注解只能用于方法

@Deprecated:用于表示某个程序元素(类, 方法等)已过时

@SuppressWarnings: 抑制编译器警告.

2.1 自定义注解:

定义新的 Annotation 类型使用@interface关键字

声明注解的属性

注解属性的作用:原来写在配置文件中的信息,可以通过注解的属性进行描述。
Annotation的属性声明方式: public   String name();   public可以不写。
属性默认值声明方式:Stringname() default “xxx”;
特殊属性value:如果注解中有一个名称value的属性,那么使用注解时可以省略value=部分,如@MyAnnotation(“xxx")
特殊属性value[];
注解属性的类型可以是:
    String类型
    基本数据类型
    Class类型
    枚举类型
    注解类型
    以上类型的一维数组

2.2 JDK的元 Annotation

@ RetentionPolicy.CLASS: 编译器将把注解记录在 class文件中. 当运行 Java 程序时, JVM 不会保留注解. 这是默认值

@Target:指定注解用于修饰类的哪个成员.@Target 包含了一个名为value,类型为ElementType的成员变量。

@Documented:用于指定被该元 Annotation 修饰的Annotation类将被 javadoc 工具提取成文档。

@Inherited:被它修饰的 Annotation 将具有继承性.如果某个类使用了被 @Inherited 修饰的Annotation,则其子类将自动具有该注解。

自定义注解:

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Inherited
public @interface StudentAnnotation {

    String name();
    int age();
   String gender();
}

使用:

import java.lang.reflect.Method;


 @StudentAnnotation(name="lisi",age=26,gender = "男")
public class Student {

    @StudentAnnotation(name="张三",age=26,gender = "男")
    public void show()throws Exception{
      //获取方法上面的注解
        Class clazz = Class.forName("com.vince.practice04.Fanshe.Zhujie.zhijie1.Student");
        //获取方法
        Method show = clazz.getMethod("show");
        // 获取方法上面的注解
        StudentAnnotation annotation = show.getAnnotation(StudentAnnotation.class);
        //获取注解属性
        String name = annotation.name();
        int age = annotation.age();
        String gender = annotation.gender();


        System.out.println("学生信息:"+name+" "+age+" "+gender);
    }

}

测试:

public class Test {
    public static void main(String[] args)throws Exception {
        Student  stu=new Student();
        stu.show();
    }
}

 

第五节:XML语言

5.1为什么使用XML

问题1:Windows系统的应用怎么和Linux系统中的应用交互数据

问题2:其它诸如此类跨平台、跨操作系统的数据交互问题……

使用XML解决。

5.2XML概述

可扩展性标记语言(eXtensible Markup Language),文件扩展名.xml

用途:描述、传输数据

使用场合:

◦持久化存储数据

◦数据交换

◦数据配置

 

第六节:XML解析

XML解析方式

1   DOM解析     2  SAX解析    

DOM和SAX比较

DOM解析 (Document Object Model) 文档对象模型
    易用性强,使用DOM时,将把所有的XML文档信息都存于内存中,并且遍历简单,支持XPath,增强了易用性。
    效率低,解析速度慢,内存占用量过高,对于大文件来说几乎不可能使用
    支持增删改查
SAX解析(Simple API for Xml)
    SAX是一个用于处理XML事件驱动的“推”模型,虽然它不是W3C标准,但它却是一个得到了广泛认可的API
    SAX模型最大的优点是内存消耗小
    只适合读取。

使用Dom解析:

 

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.FileReader;
import java.io.FileWriter;
import java.util.List;

public class Demo01 {
    public static void main(String[] args) throws Exception{
       //  1 创建SaxReader读取器
        SAXReader reader = new SAXReader();
        // 2 读取 返回document 对象(Dom树)
        Document document = reader.read(new FileReader("books.xml"));
        // 3
        Element root = document.getRootElement();
        // 4 获取子节点
        List booklist = root.elements("book");
        // 5 遍历
        for (Element element : booklist) {

            //获取属性
            String id=element.attributeValue("id");
            String name=element.elementText("name");
            String sex=element.elementText("sex");

            System.out.println(id+name+sex);
        }

        // 6 添加节点
        Element newbook = root.addElement("book");
        // 添加属性
             newbook.addAttribute("id", "1004");
             newbook.addElement("name").setText("手机开发");
             newbook.addElement("sex").setText("男");
             newbook.addElement("price").setText("1009");

          //写入
        OutputFormat format= OutputFormat.createPrettyPrint();//创建一个漂亮的输出格式
        format.setEncoding("utf-8");
         XMLWriter writer=new XMLWriter(new FileWriter("src\\books.xml"), format);
        //XMLWriter writer=new XMLWriter(new FileWriter("src\\books2.xml"), format);
          writer.write(document);
          writer.close();
        System.out.println("写入成功1");

    }
}

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Java-反射和XML.)