了解反射

java反射机制:内存中获取java中的属性和方法的操作。
首先反射的一个类用于操作反射:Class - java.lang包下

获取类:我们操作中的new关键字其实在java的内存中作了几件事:**

  1. 先找到构造函数(有参、无参)
  2. 反射中私有属性不一定要提供set/get方法,因为在反射中我们不需要调用方法,直接在构造函数中处理就可以。
  3. 反射中能够调用方法,利用method对象进行方法的处理
  4. 反射中获取类的方式有三种,但是这些获取到的类一定是同一个:==比较时true,地址的指向一致
  5. 反转中可以获取私有的和公有的字段

**

反射处理公共字段

  1. package review;
  2. import org.junit.Test;
  3. import java.lang.reflect.Field;
  4. /**
  5. * 反射用于处理属性
  6. *
  7. * 利用Student进行操作
  8. */
  9. public class FieldTest1 {
  10. @Test
  11. //这个方法的返回值只能是void,并且不能传参
  12. public void test1(){
  13. //常规的给类中public字段赋值
  14. Student s = new Student();
  15. s.setId(11);
  16. System.out.println(s);
  17. }
  18. //反射处理公共字段
  19. @Test
  20. public void test2() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
  21. //1.获取反射类 - Class对象
  22. Class cla = Class.forName("review.Student");
  23. //2.创建该类的实例
  24. Object s1 = cla.newInstance();
  25. System.out.println(s1);//Student{id=0, name='null'}
  26. //3.处理字段 - java.lang.reflect.Field
  27. Field f_id = cla.getField("id");
  28. System.out.println(f_id);//public int review.Student.id
  29. //4.赋值 - 第一个参数是当前所在的类,第二个参数是值
  30. f_id.set(s1,30);
  31. System.out.println(s1);//Student{id=30, name='null'}
  32. //5.获取字段的值
  33. Object id_value = f_id.get(s1);
  34. System.out.println(id_value);//30
  35. }
  36. }

反射处理私有字段

使用的方法getDeclaredField(); (带有Declared的方法)
赋值操作要先破解访问权限 - 打破私有访问权限 - setAccessible(true);

package review;

import org.junit.Test;

import java.io.ObjectInputStream;
import java.lang.reflect.Field;

/**
 * 反射用于处理属性
 *
 * 利用Student进行操作
 */
public class FieldTest2 {
    //反射处理私有字段
    @Test
    public void test2() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
        //1.获取反射类 - Class对象
        Class cla = Class.forName("review.Student");
        //2.创建该类的实例
        Object s1 = cla.newInstance();
        System.out.println(s1);//Student{id=0, name='null'}
        //3.处理私有字段 - java.lang.reflect.Field
        Field f_name = cla.getDeclaredField("name");
        System.out.println(f_name);//private java.lang.String review.Student.name
        //4.打破私有访问权限
        f_name.setAccessible(true);
        //5.赋值
        f_name.set(s1,"段誉");
        System.out.println(s1);//Student{id=0, name='段誉'}
        //6.获取值
        Object s1_name = f_name.get(s1);
        System.out.println(s1_name);//段誉

    }
}

映射Properties

概述

Properties类是java中提供的(支持度很高的)专门用于处理属性配置文件的一个api
通常用于属性文件的配置以持久化属性的作用。

该类来自于java.util包下的,是Map接口的子类,间接继承了Map - 键值对(双列)

特点:
1.Map接口的子类,map中的方法都可以使用
2.该集合没有泛型,键值都是字符串
3.是一个可以持久化的属性集,键值存储到集合中,也可以持久化到设备(硬盘,u盘等等)上。
4.有和流结合的技术

常用方法:**

  • public Object setProperty(String key,String value)向Properties里加入元素(实现是调用了Map的put方法)
  • public Set StringPropertyNames() - 返回此属性列表(Properties)中的键集
  • public String getProperty(String key) - 指定key的value

**

Properties写入文件

  • 将集合中的内容存储到文件中
    • store(OutputStream,content) - content写入文件的内容(单独的,不是集合里的)
    • store(Writer,content) - BufferedWriter实现
  • 读取文件的数据,并加入Properties集合
    • load(InputStream)
    • load(Reader)

**

package Properties;

import org.junit.Test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

/**
 * 讲解Properties使用
 */
public class PropertiesDemo {
    //使用步骤:
    @Test
    public void test1() throws IOException {
        //1.保存properties的数据到流中 - void store(OutputStream out,String comment)
        Properties prop = new Properties();
        prop.put("id","100");
        prop.put("name","john");
        prop.store(new FileOutputStream("a.txt"),"冲冲冲,杀了麻生");//内容转换成了Unicode码
    }

    //从流中读取 - void load(InputStream in)
    @Test
    public void test2() throws IOException {
        Properties prop = new Properties();
        prop.load(new FileInputStream("a.txt"));
        System.out.println(prop);//{name=john, id=100}
        //建议将数据强制转成字符串
        String v_id = prop.getProperty("id");
        System.out.println(v_id);//100
        String v_name = prop.getProperty("name");
        System.out.println(v_name);//john
    }

    @Test
    public void test3() throws IOException {
        //设置数据 - setProperty(String key,String Value)
        Properties prop = new Properties();
        prop.setProperty("id","20");
        //持久化数据
        prop.store(new FileOutputStream("a.txt"),"要写入的内容");
    }

    @Test
    public void test4() throws IOException {
        //获取数据 - String getProperties(String key)
        Properties prop = new Properties();
        //先通过流读取文件
        prop.load(new FileInputStream("a.txt"));
        System.out.println(prop);//{id=20}
        String v_id = prop.getProperty("id");
        String v_name = prop.getProperty("name");
        System.out.println(v_id);//20
        System.out.println(v_name);//null
        //如果key找不到则返回null
    }
}