反射
1,反射机制有什么用?
通过java语言中的反射机制可以操作字节码文件。有点类似于黑客。(可以读和修改字节码文件)。通过反射机制可以操作代码片段(class文件)
2,反射机制的相关类在哪个包下?
java.lang.reflect.*.
3, 反射机制相关重要的类有哪些?
java.lang.Class: 代表整个字节码,代表一个类。
java.lang.reflect.Mathod: 代表字节码中的方法字节码。
java.lang.reflect.Constructor: 代表字节码中的构造方法字节码。
java.lang.reflect.Field: 代表字节码中属性字节码。
要操作一个类的字节码,需要首先获取到这个类的字节码,怎么获取?
java.lang.Class实例? 三种方法
1)Class c = Class.forName("完整类名带包名");
2) Class c = 对象.getClass();
3) Class c = 任何类型.class();
什么叫类路径下?放在src下的都是类路径下。src是类的根路径
String paht = Thread.currentThread().getContextClassLoader().getResource("").getPath(); 采用这个代码可以得到绝对路径。
Thread.currentThread() ;当前线程对象。
getContextClassLoader();是线程对象的方法,可以获得当前的类加载器对象。
getResource(); [获取资源]这是类加载器对象的方法,当前线程的类加载器默认从类的根路径下加载资源。
资源绑定器在java.util包下,便于获取属性配置文件中的内容。使用以下这种方式的时候,属性配置文件xxx.properties必须放在类路径下。
ResourceBudle budle = ResourceBudle.getBundle("classinfo");
System.out.println(budle.getString("className");
4, 类加载器
1)什么是类加载器?
专门负责加载类的命令/工具。 classLoader
2),JDK中自带的3个类加载器。
1》启动类加载器 2》扩展类加载器 3》应用类加载器
3),假设有这样一段代码: String s = "abc';
代码开始执行之前,会将所需要的类全部加载到JVM当中,通过类加载器,看到以上代码类加载器会找到String.class文件。
怎么加载:
首先通过”启动类加载器“加载 c:\program Files \java\jdk1.8.0-101\jre\lib\rt.jar
如果加载不到,会通过”扩展加载器“加载 : c:\program Files \java\jdk1.8.0-101\jre\lib\ext\*.jar
如果还没有,会通过”应用加载器“加载 ,应用加载器专门加载: ClassPath中的类
public class Student { public String name ; public Integer age; public Student(String name, Integer age) { this.name = name; this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } } //////////////////////////////////////////////////////////////////////////////////////////
//反射student类中所有的Field public class Reflect01 { public static void main(String[] args) throws ClassNotFoundException { Class studentClass = Class.forName("com.atping.reflect_.Student"); Field[] fields = studentClass.getFields();//获取类中所有的属性 for (Field field : fields) { System.out.println(field.getName()); //遍历属性名字 name age Class<?> type = field.getType(); //获取属性的类型 System.out.println(type.getName()); } System.out.println("拿到全类名" + studentClass.getName()); System.out.println("类名" + studentClass.getSimpleName()); } }
5, 反射的注意事项
使用反射机制,怎么去访问一个对象的属性。(set get)
Class studentClass = Class.forName("com.atping.student");
Object obj = studentClass.newInstance(); obj就是student对象
获取no属性,根据属性的名称获取Field
Field nofield = studentClass.getDeclaredField("no");
nofield.set(obj,2022); // 给obj对象的no属性赋值2022
sout(nofield.get(obj)); //打印出来
反射机制让代码复杂了还是灵活了?
可以访问私有属性吗?Field nameField = studentClass.getDeclaredField("name"); 打破封装
nameField.setAccessible(true);
nameField.set(obj,"jdbc:");
sout(nameField.get(obj));
public class StudentTest { /** * 传统方法 三要素: 要素1: 对象s * 要素2: 属性age * 要素3 : 赋值 tom * System.out.println(s.getName() + s.getAge()); * 读取属性 两要素: 1.获取s对象的age和name属性的值 */ @Test public void Test(){ Student s = new Student(); s.setAge(30); s.setName("tom"); System.out.println(s.getName() + s.getAge()); } @Test public void Test02() throws Exception { Class studentClass = Class.forName("com.atping.demo_.Student"); Object obj = studentClass.newInstance(); //obj就是student对象 Field noField = studentClass.getDeclaredField("age"); noField.set(obj,28); //给obj对象的age属性赋值 System.out.println(noField.get(obj)); Field nameField = studentClass.getDeclaredField("name"); nameField.setAccessible(true); nameField.set(obj,"jack"); System.out.println(nameField.get(obj)); } }

浙公网安备 33010602011771号