Reflection(反射)是被视为动态语言的关键,反射机制容许程序在执行期 借助于Reflection API取得任何类的内部信息,并能直接操做任意对象的内 部属性及方法。java
加载完类以后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。咱们能够经过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,因此,咱们形象的称之为:反射。mysql
正常方式: 引入须要的包名称 → 经过new实例化对象 → 取得实例化对象
反射方式: 经过实例化对象 → getClass()方法 → 获得完整的包名称面试
Java反射机制提供的功能算法
在运行时判断任意一个对象所属的类。
在运行时构造任意一个类的对象。
在运行时判断任意一个类所具备的成员变量和方法。
在运行时获取泛型信息。
在运行时调用任意一个对象的成员变量和方法。
在运行时处理注解。
生成动态代理。spring
public class Person { private String name; public int age; public void show() { System.out.println("您好!世界"); } private String showNation(String nation){ System.out.println("个人国际是:" + nation); return nation; } private Person(String name) { this.name = name; } ..... } public void test2() throws Exception { Class clazz = Person.class; // 1.经过反射,建立Person类的对象 Constructor cons = clazz.getConstructor(String.class, int.class); Object obj = cons.newInstance("Tom", 12); Person p = (Person) obj; System.out.println(p.toString()); // 2.经过反射,调用指定的属性、方法、对象 // 调属性 Field age = clazz.getDeclaredField("age"); age.set(p,10); System.out.println(p.toString()); // 调方法 Method method = clazz.getDeclaredMethod("show"); method.invoke(p); // 经过反射是能够调用私有的属性、方法、构造器 // 调用私有构造器 Constructor cons1 = clazz.getDeclaredConstructor(String.class); cons1.setAccessible(true); Person p1 = (Person) cons1.newInstance("Jerry"); System.out.println(p1); // 调用私有方法 Field name = clazz.getDeclaredField("name"); name.setAccessible(true); name.set(p1,"Han"); System.out.println(p1); // 调用私有方法 Method method1 = clazz.getDeclaredMethod("showNation", String.class); method1.setAccessible(true); String invoke = (String) method1.invoke(p1, "中国"); System.out.println(invoke); }./*欢迎加入java交流Q君样:909038429一块儿吹水聊天
java.lang.Class类的理解
类的加载过程:程序通过java.exe命令之后,会生成一个或多个字节码文件(.class),接着使用java.exe命令对字节码进行解释运行。至关与将某个字节码文件加载到内存中,此过程称为类的加载。加载到内存中的类,咱们称之为运行时类,此运行时类,就做为Class的一个实例。
Class的实例就是对应着一个运行时类。
加载到内存中的运行时类,会缓存必定的时间。在此时间以内,咱们能够经过不一样方式来获取从运行时类。sql
// 获取Class的实例的方法 public void test3() throws ClassNotFoundException { // 方式一:调用运行时类的属性.class Class clazz1 = Person.class; // 方式二:经过运行时类的对象 Person person = new Person(); Class clazz2 = person.getClass(); // 方法三:调用Class的静态方法forName(String classPath) Class clazz3 = Class.forName("com.tyt.java.Person"); // 方式四:类的加载器 ClassLoader ClassLoader classLoader = ReflectionTest.class.getClassLoader(); Class clazz4 = classLoader.loadClass("com.tyt.java.Person"); System.out.println(clazz1 == clazz2); System.out.println(clazz2 == clazz3); System.out.println(clazz3 == clazz4); }
Class实例能够是那些结构的说明:数组
public void test5() { Class c1 = Object.class; Class c2 = Comparable.class; Class c3 = String[].class; Class c4 = int[][].class; Class c5 = ElementType.class; Class c6 = Override.class; Class c7 = int.class; Class c8 = void.class; Class c9 = Class.class; int[] a = new int[10]; int[] b = new int[100]; Class c10 = a.getClass(); Class c11 = b.getClass(); // 只要数组元素类型与维度同样,就是同一个Class System.out.println(c10 == c11);// true }
使用Properties:用于读取配置文件。缓存
// 目录结构 // |--module // |---stc // |----com.tyt.java // |-----PropertiesTest.java // |-----jdbc1.properties // |--jdbc.properties public void test2() { String user = null; String passwored = null; FileInputStream inputStream = null; try { Properties properties = new Properties(); // 读取配置方式一: // inputStream = new FileInputStream("jdbc.properties"); // properties.load(inputStream); // 读取配置方式二:使用ClassLoader // 配置文件默认识别为:当前module的src下 ClassLoader classLoader = ClassLoaderTest.class.getClassLoader(); InputStream inputStream1 = classLoader.getResourceAsStream("jdbc1.properties"); properties.load(inputStream1); user = properties.getProperty("user"); passwored = properties.getProperty("passwored"); System.out.println("user = " + user + ",passwored = " + passwored); } catch (IOException e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }
最新2020整理收集的一些高频面试题(都整理成文档),有不少干货,包含mysql,netty,spring,线程,spring cloud、jvm、源码、算法等详细讲解,也有详细的学习规划图,面试题整理等,须要获取这些内容的朋友请加Q君样:909038429
/./*欢迎加入java交流Q君样:909038429一块儿吹水聊天jvm