Java 核心类库之反射机制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 核心类库之反射机制相关的知识,希望对你有一定的参考价值。
1:什么是反射机制?
2:反射机制它可以做什么呢?
3:反射机制对应的API又是什么?
1):通过反射机制来获取一个对象的全限定名称(完整包名),和类名;
7):获取一个类中所有的构造器,获取单个不带参数的构造器,获取带参数的构造器
9):动态加载资源文件
1.什么是反射机制
反射机制是在运行状态中,对于任意一个类,都能够知道类所有的属性和方法,对于任意一个对象,
都能调用它的方法和属性,这种动态获取方法和属性,动态调用方法和属性的功能,称为Java的反射机制。
2.反射机制它可以做什么
反射机制主要提供以下功能:
1:在运行时,判断任意一个对象所属的类 。
2:在运行时,构造任意一个类的对象。
3:在运行时,判断任意一个类所具有的成员变量和方法。
4:在运行时,任意调用一个类中的方法。
5:生成动态代理。
5.反射机制对应的API又是什么
通过一个对象来获取一个对象的全限定名称(完整包名)
包名:Classinstance 类名:MethodD
private static void GetName() { Class claz=MethodD.class;//获取对象的类 String classname=claz.getName(); System.out.println(classname);//打印出:Classinstance.MethodD }
实例化Class对象
package net.xsoftlab.baike; public class TestReflect { public static void main(String[] args) throws Exception { Class<?> class1 = null; Class<?> class2 = null; Class<?> class3 = null; // 一般采用这种形式 class1 = Class.forName("net.xsoftlab.baike.TestReflect"); class2 = new TestReflect().getClass(); class3 = TestReflect.class; System.out.println("类名称 " + class1.getName()); System.out.println("类名称 " + class2.getName()); System.out.println("类名称 " + class3.getName()); } }
获取对象的父类与实现的接口
package Classinstance; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.Serializable; //获取父类和实现的接口 public class GetparentAndInterface implements Serializable,ActionListener { public static void main(String[] args) { Class<?> claz=GetparentAndInterface.class;//获取对象 //获取父类 //返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。 Class<?>parent=claz.getSuperclass(); System.out.println(parent);//打印父类:class java.lang.Object //获取该类中所有的实现接口 // getInterfaces()确定此对象所表示的类或接口实现的接口。 Class<?>[] InterFace=claz.getInterfaces(); for (Class<?> class1 : InterFace) { System.out.println(class1); } } public void actionPerformed(ActionEvent e) { } }
使用反射来调用方法
package Classinstance; import java.lang.reflect.Method; //使用反射调用方法 class InvokeClass { public void methodOne() { System.out.println("调用不带参数的方法!"); } public void methodTwo(String name) { System.out.println("调用带一个参数的方法!" + name); } private String methodThree(String name, int age) { System.out.println("调用私有带两个参数的方法!" + name + "," + age); return name + "," + age; } } public class MethodInvokeDemo { public static void main(String[] args) throws Exception { //获取类对象 Class<InvokeClass> clazz = InvokeClass.class; //获取方法 Method md = clazz.getMethod("methodOne"); Object dowork = md.invoke(clazz.newInstance());//invoke(); System.out.println(dowork); //调用带参数的方法 Method md1 = clazz.getMethod("methodTwo", String.class); Object dowork1 = md1.invoke(clazz.newInstance(), "张三");//invoke(); System.out.println(dowork1); //调用私有带两个参数的方法 Method md2 = clazz.getDeclaredMethod("methodThree", String.class, int.class); md2.setAccessible(true);//设置可访问的私有成员 Object dowork2 = md2.invoke(clazz.newInstance(), "张三", 18);//invoke(); System.out.println(dowork2);
//使用反射调用静态方法
Method md3 = clazz.getDeclaredMethod("methodThree", String.class, int.class);
md3.setAccessible(true);//设置可访问的私有成员
Object dowork3 = md3.invoke(null, "张三", 18);//invoke();
System.out.println(dowork3); } }
使用反射来调用数组参数(情况1:数组元素类型数基本类型 情况2:数组元素类型是引用类型)
package Classinstance; import java.lang.reflect.Method; import java.util.Arrays; class Method2 { public static void dowork(int[] arr) { System.out.println("dowork被调用了" + Arrays.toString(arr)); } public static void dowork2(String[] arr) { System.out.println("dowork2被调用了" + Arrays.toString(arr)); } } public class MethodInvokeDemo2 { //使用反射调用数组参数(可变参数) public static void main(String[] args) throws Exception { Class<Method2> clazz = Method2.class; //情况1:数组元素类型数基本类型 Method md = clazz.getMethod("dowork", int[].class); //md.invoke(null, 1,2,3,4,5,6);error //Object dw=md.invoke(null, new int[]{1,2,3,4,5,6}); Object dw = md.invoke(null, new Object[] { new int[] { 1, 2, 3, 4, 5, 6 } }); System.out.println(dw); //情况2:数组元素类型是引用类型 Method md1 = clazz.getMethod("dowork2", String[].class); //md.invoke(null, new String[]{"a","b","c"});error Object dw1 = md1.invoke(null, new Object[] { new String[] { "a", "b", "c" } }); System.out.println(dw1); } }
使用反射机制,动态拷贝数组
package Classinstance; import java.lang.reflect.Array; import java.util.Arrays; //使用反射机制,动态拷贝数组 public class ArrayDemo { public static void main(String[] args) { int[] src = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; int[] dest = new int[10]; System.out.println(Arrays.toString(src)); Arraycopy(src, 2, dest, 3, 5); System.out.println(Arrays.toString(dest)); } public static void Arraycopy(Object src, int srcPos, Object dest, int destPos, int length) { //源数组和目标数组必须是数组类型 if (!src.getClass().isArray() || !dest.getClass().isArray()) { throw new ArrayStoreException("源数组和目标数组不是数组类型"); } //源数组和目标数组不能为null if (src == null || dest == null) { throw new NullPointerException("源数组和目标数组不能为null"); } //源数组和目标数组的数组类型必须一致 if (src.getClass().getComponentType() != dest.getClass().getComponentType()) { throw new ArrayStoreException("源数组和目标数组元素类型不一致"); } //源数组和目标数组不想索引越界 if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > Array.getLength(src) || destPos + length > Array.getLength(dest)) { throw new IndexOutOfBoundsException("索引越界"); } //获取需要拷贝的元素 for (int index = srcPos; index < srcPos + length; index++) { //给目标数组数组元素 Object val = Array.get(src, index); Array.set(dest, destPos, val); destPos++; } } }
获取类中的所有的方法或者单个方法
package Classinstance; import java.lang.reflect.Method; class MethodD { public void method1() { } public void method2(String name) { } private String method3(String name, int age) { return name + "," + age; } } public class GetMethodDemo { private static GetMethodDemo class2; //使用反射获取类中的方法 public static void main(String[] args) throws Exception { getAll(); getOne(); GetName(); } //通过一个对象来获取一个对象的全限定名称(完整包名) private static void GetName() { Class claz = MethodD.class;//获取对象的类 String classname = claz.getName(); System.out.println(classname);//打印出:Classinstance.MethodD } //获取类中的指定的一个方法 private static void getOne() throws Exception { Class<MethodD> clasz = MethodD.class; //获取类不带参数的方法 Method md = clasz.getMethod("method1"); //获取类中指定带一个参数的方法 Method md1 = clasz.getMethod("method2", String.class); //获取类私有指定带两个参数的方法 Method md2 = clasz.getDeclaredMethod("method3", String.class, int.class); System.out.println(md2); } private static void getAll() {//获取类中的所有方法 Class<MethodD> clasz = MethodD.class; /* * 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法, * 包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。 */ Method[] md = clasz.getDeclaredMethods(); System.out.println(md.length); for (Method method : md) { System.out.println(method); } } }
获取一个类中所有的构造器,获取单个不带参数的构造器,获取带参数的构造器
package Classinstance; import java.lang.reflect.Constructor; class User { public User() { } public User(String name) { } private User(String name, int age) { } } //获取构造器 public class GetConstructor { public static void main(String[] args) throws Exception { getAll(); } //获取所有构造器 private static void getAll() throws Exception { //1):获取构造器所在类的对象 Class<User> claz = User.class; //2):获取对象中的所有构造器 Constructor<?>[] con = claz.getConstructors();//getConstructors()获取类中带public的构造器,返回一个Constructors数组 for (Constructor<?> constructor : con) { System.out.println(constructor); } Constructor<?>[] con1 = claz.getDeclaredConstructors();//getDeclaredConstructors()获取类中带所有的构造器,跟访问权限无关,返回一个Constructors数组 for (Constructor<?> constructor : con1) { System.out.println(constructor); } //获取public User()的构造器 Constructor<User> con2 = claz.getConstructor(); System.out.println(con2); // 获取public User(String name)的构造器 //注意:必须用getDeclaredConstructor();有访问权限才可以 Constructor<User> con3 = claz.getDeclaredConstructor(String.class, int.class); System.out.println(con3); } }
使用反射调用构造器---->创建对象
package Classinstance; //使用反射调用构造器-->创建对象 import java.lang.reflect.Constructor; class Peson { public Peson() { System.out.println("无参数构造器"); } public Peson(String name) { System.out.println("有参数构造器" + name); } private Peson(String name, int age) { System.out.println("有参数构造器" + name + "," + age); } } public class CteateObject { public static void main(String[] args) throws Exception { Cteate(); } public static void Cteate() throws Exception { //获取构造器对象 Class<Peson> clasz = Peson.class; Constructor<?> con1 = clasz.getDeclaredConstructor(); Constructor<?> con2 = clasz.getDeclaredConstructor(String.class); Constructor<?> con3 = clasz.getDeclaredConstructor(String.class, int.class); //创建对象 con2.newInstance("张三");//newInstance();创建此 Class 对象所表示的类的一个新实例 //设置构造器可以访问 con3.setAccessible(true); con3.newInstance("李四", 15); } }
动态加载资源文件
package Classinstance; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Properties; //动态加载资源文件 public class LoadResourceDemo { public static void main(String[] args) throws Exception { text1(); text2(); } //最好用的方法 private static void text2() throws Exception { Properties p = new Properties(); ClassLoader loader = Thread.currentThread().getContextClassLoader(); InputStream inStream = loader.getResourceAsStream("db.properties"); p.load(inStream); System.out.println(p); } private static void text1() throws Exception { //一般方式 Properties p = new Properties(); InputStream inStream = new FileInputStream("file/db.properties");// p.load(inStream); System.out.println(p); } }
以上是关于Java 核心类库之反射机制的主要内容,如果未能解决你的问题,请参考以下文章