ellende 2019-06-25
package test; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; public class Demo_reflect { public static void main(String[] args) throws Exception { Juicer j = new Juicer(); BufferedReader br = new BufferedReader(new FileReader("config.properties")); Class clazz = Class.forName(br.readLine()); Fruit f = (Fruit)clazz.newInstance(); j.run(f); } } interface Fruit { public void squeeze(); } class Juicer { public void run(Fruit f) { f.squeeze(); } } class Apple implements Fruit { public void squeeze() { System.out.println("苹果汁好了"); } } class Orange implements Fruit { public void squeeze() { System.out.println("橘子汁好了"); } }
package com.test; import java.io.BufferedReader; import java.io.FileReader; import java.lang.reflect.Constructor; public class Demo_reflect_1 { //拿到Person类的有参构造函数并创建对象 public static void main(String[] args) throws Exception { //拿到Person的字节码文件 BufferedReader br = new BufferedReader(new FileReader("config.properties")); Class clazz = Class.forName(br.readLine()); //获取Person的有参构造函数 Constructor c = clazz.getConstructor(String.class,int.class); //创建Person对象【有参】 Person p = (Person)c.newInstance("张三",23); //打印 System.out.println(p); } }
针对非私有的成员变量
针对私有的成员变量
package com.test; import java.io.BufferedReader; import java.io.FileReader; import java.lang.reflect.Constructor; import java.lang.reflect.Field; public class Demo_reflect_2 { /** * @param args * 通过反射的方式获得成员变量并修改 * @throws Exception * @throws ClassNotFoundException */ public static void main(String[] args) throws ClassNotFoundException, Exception { //通过IO流读取配置文件 BufferedReader br = new BufferedReader(new FileReader("config.properties")); //获取字节码文件 Class clazz = Class.forName(br.readLine()); //通过获取的字节码文件获取有参构造函数 Constructor c = clazz.getConstructor(String.class,int.class); //通过获取的有参构造新建一个完成初始化的Person对象 Person p = (Person)c.newInstance("张三",23); //1.属性非私有的情况 // //获取字节码文件中的指定字段name // Field f = clazz.getField("name"); // //通过获取的指定字段修改Person对象的name属性 // f.set(p,"李四"); // //2.私有的情况【使用暴力反射】 //获取字节码文件中的指定字段name Field f = clazz.getDeclaredField("name"); //去除私有权限 f.setAccessible(true); //通过获取的指定字段修改Person对象的name属性 f.set(p,"李四"); //打印测试 System.out.println(p); } }
获取无参的方法
获取有参的方法
package com.test; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Method; /** * @author XPS * 通过反射获取方法并使用 */ public class Demo_reflect_3 { public static void main(String[] args) throws Exception, Exception { //获取字节码文件 BufferedReader br = new BufferedReader(new FileReader("config.properties")); Class clazz = Class.forName(br.readLine()); //通过获取的字节码文件获取有参构造函数 Constructor c = clazz.getConstructor(String.class,int.class); //新建一个初始化的Person对象p Person p = (Person)c.newInstance("张三",23); // //1. 获取无参方法 // //通过反射获得这个字节码中的方法eat // Method m = clazz.getMethod("eat"); // //运行p的eat方法 // m.invoke(p); //2. 获取有参方法 //通过反射获得这个字节码中的方法eat(int num) Method m = clazz.getMethod("eat",int.class); //运行p的eat方法 m.invoke(p,2); } }
泛型只在编译期有效,运行期将被擦除,而反射是在运行期获取字节码文件来调用方法添加我们想要添加的字符串
package com.test; import java.lang.reflect.Method; import java.util.ArrayList; /** * @author XPS * 使用反射技术绕过泛型检查,实现往ArrayList<Integer>中添加字符串"abc" * * 原理: 泛型只在编译期有效,运行期将被擦除,而反射是在运行期获取字节码文件来调用方法添加我们想要添加的字符串 * */ public class Demo_reflect_4 { public static void main(String[] args) throws Exception { ArrayList<Integer> list = new ArrayList<>(); list.add(111); list.add(222); //list.add("abc"); //这个地方填加字符串会报错 Class clazz = Class.forName("java.util.ArrayList"); Method m = clazz.getMethod("add",Object.class); m.invoke(list, "abc"); System.out.println(list); } }
package com.test; public class Demo_reflect_5 { public static void main(String[] args) throws Exception { Student stu = new Student("张三",23); Tool.setProperty(stu, "name", "李四"); System.out.println(stu); } } class Student { private String name; private int age; public Student() { super(); // TODO Auto-generated constructor stub } public Student(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }
package com.test; import java.lang.reflect.Field; public class Tool { public static void setProperty(Object obj, String propertyName, Object value) throws Exception, SecurityException { Class clazz = obj.getClass(); Field f = clazz.getDeclaredField(propertyName); f.setAccessible(true); f.set(obj, value); } }
package com.test; import java.io.BufferedReader; import java.io.FileReader; import cn.itcast.heima.DemoClass; public class Demo_reflect_6 { /** * @param args * * 已知一个类,定义如下: * package cn.itcast.heima; public class DemoClass { public void run() { System.out.println("welcome to heima!"); } } (1) 写一个Properties格式的配置文件,配置类的完整名称。 (2) 写一个程序,读取这个Properties配置文件,获得类的完整名称并加载这个类,用反射的方式运行run方法。 * @throws Exception * @throws ClassNotFoundException * */ public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new FileReader("XXX.properties")); Class clazz = Class.forName(br.readLine()); DemoClass d = (DemoClass)clazz.newInstance(); d.run(); } }
package cn.itcast.heima; public class DemoClass { public void run() { System.out.println("Welcome to heima!"); } }
留坑待填
定义一个算法的骨架,而将具体的算法延迟到子类中实现
使用模板方法模式在定义算法骨架的同时,可以灵活的实现具体算法,满足用户灵活多变的需求。
如果算法骨架有修改,需要修改抽象类
package com.test; public class Demo_reflect_9 { public static void main(String[] args) { long start = System.currentTimeMillis(); for(int i = 0; i < 100000; i++) { System.out.println("x"); } long end = System.currentTimeMillis(); System.out.println(end - start); } }
package com.test; public class Demo_reflect_9 { public static void main(String[] args) { Demo d = new Demo(); System.out.println(d.getTime()); } } abstract class GetTime { public final long getTime() { long start = System.currentTimeMillis(); code(); long end = System.currentTimeMillis(); return end - start; } public abstract void code(); } class Demo extends GetTime { @Override public void code() { for(int i = 0; i < 100000; i++) { System.out.println("x"); } } }
叨逼叨两句收拾收拾~18-11:Collection中的常见方法sortpackage com.test.demo001;System.out.println; //根据默认排序结果获取集合中的最大值