Class类的常用方法 | 解释 |
---|---|
static Class forName(String name) | 返回指定类名name的Class对象 |
Object newInstance() | 调用缺省构造函数,返回该Class对象的一个实例 |
getName() | 返回此Class对象所表示的实体(类、接口、数组类、基本类型或void)名称 |
Class getSuperClass() | 返回当前Class对象的父类的Class对象 |
Class [] getInterfaces() | 获取当前Class对象的接口 |
ClassLoader getClassLoader() | 返回该类的类加载器 |
Class getSuperclass() | 返回表示此Class所表示的实体的超类的Class |
Constructor[] getConstructors() | 返回一个包含某些Constructor对象的数组 |
Field[] getDeclaredFields() | 返回Field对象的一个数组 |
Method getMethod(String name,Class … paramTypes) | 返回一个Method对象,此对象的形参类型为paramType |
String str = "test4.Person"; Class clazz = Class.forName(str); Object obj = clazz.newInstance(); Field field = clazz.getField("name"); field.set(obj, "Peter"); Object name = field.get(obj); System.out.println(name);
前提:若已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高
实例:Class clazz = String.class;
前提:已知某个类的实例,调用该实例的getClass()方法获取Class对象
实例:Class clazz = “www.atguigu.com”.getClass();
前提:已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出ClassNotFoundException
实例:Class clazz = Class.forName(“java.lang.String”);
其他方式(不做要求)
ClassLoader cl = this.getClass().getClassLoader();
Class clazz4 = cl.loadClass(“类的全类名”);
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);
public class ClassLoadingTest { public static void main(String[] args) { System.out.println(A.m); } } class A { static { m = 300; } static int m = 100; } //第二步:链接结束后m=0 //第三步:初始化后,m的值由<clinit>()方法执行决定 // 这个A的类构造器<clinit>()方法由类变量的赋值和静态代码块中的语句按照顺序合并产生,类似于 // <clinit>(){ // m = 300; m = 100; // }
public class ClassLoadingTest { public static void main(String[] args) { // 主动引用:一定会导致A和Father的初始化 // A a = new A(); // System.out.println(A.m); // Class.forName("com.cxb.A"); // 被动引用 A[] array = new A[5];//不会导致A和Father的初始化 // System.out.println(A.b);//只会初始化Father // System.out.println(A.M);//不会导致A和Father的初始化 } static { System.out.println("main所在的类"); } } class Father { static int b = 2; static { System.out.println("父类被加载"); } } class A extends Father { static { System.out.println("子类被加载"); m = 300; } static int m = 100; static final int M = 1; }
//1.获取一个系统类加载器 ClassLoader classloader = ClassLoader.getSystemClassLoader(); System.out.println(classloader); //2.获取系统类加载器的父类加载器,即扩展类加载器 classloader = classloader.getParent(); System.out.println(classloader); //3.获取扩展类加载器的父类加载器,即引导类加载器 classloader = classloader.getParent(); System.out.println(classloader); //4.测试当前类由哪个类加载器进行加载 classloader = Class.forName("exer2.ClassloaderDemo").getClassLoader(); System.out.println(classloader); //5.测试JDK提供的Object类由哪个类加载器加载 classloader = Class.forName("java.lang.Object").getClassLoader(); System.out.println(classloader); //6.关于类加载器的一个主要方法:getResourceAsStream(String str):获取类路径下的指定文件的输入流 InputStream in = null; in = this.getClass().getClassLoader().getResourceAsStream("exer2\\test.properties"); System.out.println(in);
调用Class对象的newInstance()方法可以创建类的对象
要求:类必须有一个无参数的构造器
类的构造器的访问权限需要足够
操作的时候明确的调用类中的构造器,并将参数传递进去之后,可以实例化操作
步骤如下:
通过Class类的getDeclaredConstructor(Class … parameterTypes)取得本类的指定形参类型的构造器
向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数。
通过Constructor实例化对象
//1.根据全类名获取对应的Class对象 String name = “atguigu.java.Person"; Class clazz = null; clazz = Class.forName(name); //2.调用指定参数结构的构造器,生成Constructor的实例 Constructor con = clazz.getConstructor(String.class,Integer.class); //3.通过Constructor的实例创建对应类的对象,并初始化类属性 Person p2 = (Person) con.newInstance("Peter",20); System.out.println(p2);
Class方法 | 解释 |
---|---|
public Class<?>[] getInterfaces() | 使用反射取得此对象所表示的类或接口实现的全部接口 |
public Class<? Super T> getSuperclass() | 此 Class 所表示的实体(类、接口、基本类型 )的父类的Class |
public Constructor[] getConstructors() | 返回此 Class 对象所表示的类的所有public构造方法 |
public Constructor[] getDeclaredConstructors() | 返回此 Class 对象表示的类声明的所有构造方法 |
public Method[] getDeclaredMethods() | 返回此Class对象所表示的类或接口的全部方法 |
public Method[] getMethods() | 返回此Class对象所表示的类或接口的public的方法 |
public Field[] getFields() | 返回此Class对象所表示的类或接口的public的Field |
public Field[] getDeclaredFields() | 返回此Class对象所表示的类或接口的全部Field |
get Annotation(Class annotationClass) | |
getDeclaredAnnotations() | |
Type getGenericSuperclass() | 获取父类泛型类型 |
ParameterizedType | 泛型类型 |
getActualTypeArguments() | 获取实际的泛型类型参数数组 |
Package getPackage() | 类所在的包 |
Constructor方法 | 解释 |
---|---|
public int getModifiers(); | 取得修饰符 |
public String getName(); | 取得方法名称 |
public Class<?>[] getParameterTypes(); | 取得参数的类型 |
Method方法 | 解释 |
---|---|
public Class<?> getReturnType() | 取得全部的返回值 |
public Class<?>[] getParameterTypes() | 取得全部的参数 |
public int getModifiers() | 取得修饰符 |
public Class<?>[] getExceptionTypes() | 取得异常信息 |
Field方法 | 解释 |
---|---|
public int getModifiers() | 以整数形式返回此Field的修饰符 |
public Class<?> getType() | 得到Field的属性类型 |
public String getName() | 返回Field的名称 |
通过反射,调用类中的方法,通过Method类完成
通过Class类的getMethod(String name,Class…parameterTypes)方法取得一个Method对象,并设置此方法操作时所需要的参数类型
之后使用Object invoke(Object obj, Object[] args)进行调用,并向方法中传递要设置的obj对象的参数信息
Object invoke(Object obj, Object … args)
说明
1.Object对应原方法的返回值,若原方法无返回值,此时返回null
2.若原方法若为静态方法,此时形参Object obj可为null
3.若原方法形参列表为空,则Object[] args为null
4.若原方法声明为private,则需要在调用此invoke()方法前,显式调用方法对象的setAccessible(true)方法,将可访问private的方法
反射机制中,可以直接通过Field类操作类中的属性,通过Field类提供的set()和get()方法就可以完成设置和取得属性内容的操作
public Field getField(String name) 返回此Class对象表示的类或接口的指定的public的Field
public Field getDeclaredField(String name)返回此Class对象表示的类或接口的指定的Field
public Object get(Object obj) 取得指定对象obj上此Field的属性内容
public void set(Object obj,Object value) 设置指定对象obj上此Field的属性内容
方法 | 解释 |
---|---|
static Class<?> getProxyClass(ClassLoader loader, Class<?>… interfaces) | 创建一个动态代理类所对应的Class对象 |
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) | 直接创建一个动态代理对象 loader类加载器,interfaces得到被代理类实现的全部接口,h得到InvocationHandler接口的实现类实例 |
// theProxy 代理类的对象 // method 要调用的方法 // params 方法调用时所需要的参数 public Object invoke(Object theProxy, Method method, Object[] params) throws Throwable{ try{ Object retval = method.invoke(targetObj, params); // Print out the result System.out.println(retval); return retval; }catch (Exception exc){} }
创建被代理的类以及接口
通过Proxy的静态方法
newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 创建一个Subject接口代理 RealSubject target = new RealSubject(); // Create a proxy to wrap the original implementation DebugProxy proxy = new DebugProxy(target); // Get a reference to the proxy through the Subject interface Subject sub = (Subject) Proxy.newProxyInstance( Subject.class.getClassLoader(),new Class[] { Subject.class }, proxy);
String info = sub.say(“Peter", 24); System.out.println(info);
public interface Dog{ void info(); void run(); } public class HuntingDog implements Dog{ public void info(){ System.out.println("我是一只猎狗"); } public void run(){ System.out.println("我奔跑迅速"); } } public class DogUtil{ public void method1(){ System.out.println("=====模拟通用方法一====="); } public void method2(){ System.out.println("=====模拟通用方法二====="); } } public class MyInvocationHandler implements InvocationHandler{ // 需要被代理的对象 private Object target; public void setTarget(Object target){ this.target = target;} // 执行动态代理对象的所有方法时,都会被替换成执行如下的invoke方法 public Object invoke(Object proxy, Method method, Object[] args) throws Exception{ DogUtil du = new DogUtil(); // 执行DogUtil对象中的method1。 du.method1(); // 以target作为主调来执行method方法Object result = method.invoke(target , args); // 执行DogUtil对象中的method2。 du.method2(); return result;}} public class MyProxyFactory{ // 为指定target生成动态代理对象 public static Object getProxy(Object target) throws Exception{ // 创建一个MyInvokationHandler对象MyInvokationHandler handler = new MyInvokationHandler(); // 为MyInvokationHandler设置target对象handler.setTarget(target); // 创建、并返回一个动态代理对象 return Proxy.newProxyInstance(target.getClass().getClassLoader() , target.getClass().getInterfaces() , handler); } } public class Test{ public static void main(String[] args) throws Exception{ // 创建一个原始的HuntingDog对象,作为target Dog target = new HuntingDog(); // 以指定的target来创建动态代理 Dog dog = (Dog)MyProxyFactory.getProxy(target); dog.info(); dog.run(); } }