java 编程基础 Class对象 反射 :获取类的构造方法,方法,成员变量,内部类,外部类,父类,实现的接口,修饰符等...
类 Class
每个类被加载之后,系统就会为该类生成一个对应的Class对象,通过该Class对象就可以访问到JVM中的这个类。
我们在Java中获取Class对象一般有三种方式:
(1), 使用Class类的forName(String className)静态方法。该方法需要传入字符串参数,该字符串参数的值是某个类的全限定类名(必须添加完整包名)。
(2), 调用某个类的class属性来获取该类对应的Class对象 例如,Person.class 将会返回Person类对应的class对象
(3), 调用某个对象的getClass()方法。该方法是 java.lang.Object 类中的一个方法,所以所有Java对象都可以调用该方法,该方法将会返回该对象所属类对应的 Class对象
public class SimpleClassTest { public static void main(String[] args) throws ClassNotFoundException { Class testcls1 = Class.forName("com.vgxit.testclass.Test"); System.out.println(testcls1); Class testcls2 = Test.class; System.out.println(testcls2); Test test = new Test(); System.out.println(test.getClass()); } }
Class对象中的信息 (反射)
1,反射构造方法:Connstructor
- Connstructor<T> getConstructor(Class... paraeterTypes): 返回此Class象对应类的、带指定形参列表的public构造器
-
Constructor<T> getDeclaredConstructor(Class... parameterTypes): 同上 ,可返回private类型的构造器
- Constructor>[] getConstructors(): 返回此Class对象对应类的所public构造器
- Constructor>[] getDeclaredConstructors(): 返回此 Class 对象对应类的所有构造器(含private的)
测试用User类
package com.zmd.classTest; public class User { private String name; private int age; public User(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
测试使用getConstructor:
public class ConstructorTest { public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException { //获取对应的Class Class<User> userClass = User.class; //获取对应参数的构造器 Constructor<User> userConstructor = userClass.getConstructor(String.class, int.class); //使用构造器.newInstance创建对象 User user = userConstructor.newInstance("V哥",18); System.out.println(user); } }
上面的User对象创建成功,它的这个构造方法是public的。果把这个构造方法修改成了private的,就需要使用getDeclaredConstructor获取 所有构造器(含私有的)
测试使用getDeclaredConstructor:
使用private的构造器,需要设置为可访问的setAccessible(true)
public class ConstructorTest { public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException { //获取对应的Class Class<User> userClass = User.class; //获取对应参数的构造器 Constructor<User> userConstructor = userClass.getDeclaredConstructor(String.class, int.class); //禁止检查java的访问控制 userConstructor.setAccessible(true); //使用构造器.newInstance创建对象 User user = userConstructor.newInstance("V哥",18); System.out.println(user); } }
获取所有的构造方法的代码:
Constructor<?>[] constructors = userClass.getDeclaredConstructors(); for (Constructor<?> constructor:constructors){ System.out.println(constructor); }
2、反射方法Method :
- Method getMethod(String name, Class... parameterTypes): 返回此 Class对象对应的带指定形参列表的public修饰的方法
- Method[] getMethods(): 返回此Class对象所表示的类的所有public方法。
- Method getDeclaredMethod(String name, Class... parameterTypes): 返回此Class对象对应类的、带指定形参列表的所有方法(含private的)
- Method[] getDeclaredMethods(): 返回此Class象对应类的全部方法,
示例User类
package com.zmd.classTest; import javax.sound.midi.Soundbank; /** * @ClassName User * @projectName: object1 * @author: Zhangmingda * @description: XXX * date: 2021/5/16. */ public class User { private static String name; private int age; private User(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } private void sayHello(String toName){ System.out.println(this.name + "说:Hello " + toName); } public static void run(){ System.out.println(name + "在疯跑..."); } }
执行反射得到的方法invoke
获取到Method方法实例.invoke(实例对象,方法args...) 执行对象的对应方法
package com.zmd.classTest; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @ClassName ConstructorMethod * @projectName: object1 * @author: Zhangmingda * @description: XXX * date: 2021/5/16. */ public class ConstructorMethod { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Constructor<User> userConstructor = User.class.getDeclaredConstructor(String.class, int.class); userConstructor.setAccessible(true); User vGe = userConstructor.newInstance("V哥",22); // Method sayHelloMethod = User.class.getMethod("sayHello", String.class);//sayHello 为public Method sayHelloMethod = User.class.getDeclaredMethod("sayHello", String.class);//sayHello 为private sayHelloMethod.setAccessible(true); //sayHello 为private sayHelloMethod.invoke(vGe,"美女"); //V哥说:Hello 美女 } }
反射静态方法,执行的时候对象传入null
package com.zmd.classTest; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @ClassName ConstructorStaticMethod * @projectName: object1 * @author: Zhangmingda * @description: XXX * date: 2021/5/16. */ public class ConstructorStaticMethod { public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException { Method runMethod = User.class.getDeclaredMethod("run"); runMethod.invoke(null); //null在疯跑... Constructor<User> constructor = User.class.getDeclaredConstructor(String.class,int.class); constructor.setAccessible(true); constructor.newInstance("v哥",22); runMethod.invoke(null); //v哥在疯跑... 所有类共享static 静态变量,创建一个类后User类的name类变量变为了v哥 } }
3、获取对应的成员变量:Field
- Field getField(String name): 返回此Classd对象对应类的、指定名称 public成员变量。
- Field[] getFields(): 返回此Class对象对应类的所有public成员变量。
- Field getDeclaredField(String name): 返回此Class对象对应类的、指定名称的成员变,与成员变的访问权限无关
- Field[] getDeclaredFields(): 返回此Class对象对应类的全部成员变量,与成员变量的访问权限无关。
package com.zmd.classTest; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; /** * @ClassName ConstructorVar * @projectName: object1 * @author: Zhangmingda * @description: XXX * date: 2021/5/16. */ public class ConstructorVar { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException { Constructor<User> constructor = User.class.getDeclaredConstructor(String.class, int.class); constructor.setAccessible(true); User vGe = constructor.newInstance("V哥",22); Field nameField = User.class.getDeclaredField("name"); Field ageField = User.class.getDeclaredField("age"); nameField.setAccessible(true); ageField.setAccessible(true); System.out.println(nameField.get(vGe)); System.out.println(ageField.get(vGe)); } }
获取静态变量,实例传入null即可
public class User { private String name; private int age; private static final String type = "中国人"; }
package com.zmd.classTest; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; /** * @ClassName ConstructorVar * @projectName: object1 * @author: Zhangmingda * @description: XXX * date: 2021/5/16. */ public class ConstructorVar { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException { Field typeField = User.class.getDeclaredField("type"); typeField.setAccessible(true); System.out.println(typeField.get(null)); //输出:中国人 //静态变量获取,对象为null即可 } }
改变实例变量:
//改变实例变量 System.out.println(vGe); //User{name='V哥', age=22} ageField.set(vGe,18); System.out.println(vGe); //User{name='V哥', age=18}
4,获取内部类:
Class[] getDeclaredClasses(): 返回该Class对象对应类里包含的全部内部类。
public class User { public static class Student{ private int grade; public void showGrade(){ System.out.println("年级是"); } } }
package com.zmd.classTest; import java.lang.reflect.InvocationTargetException; /** * @ClassName GetInnerClass * @projectName: object1 * @author: Zhangmingda * @description: XXX * date: 2021/5/16. */ public class GetInnerClass { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //获取所有内部类 Class<?>[] innerClasses = User.class.getDeclaredClasses(); for (Class<?> cls :innerClasses){ if (cls.getSimpleName().equals("Student")){ User.Student student = (User.Student) cls.getConstructor().newInstance(); student.showGrade(); //调用内部类对象的方法 cls.getMethod("showGrade").invoke(student); //反射方式调用内部类的方法 } } } }
5,通过内部类Class获取外部类:
//通过内部类获取外部类 Class<User.Student> studentClass = User.Student.class; Class<User> userClass = (Class<User>)studentClass.getDeclaringClass(); System.out.println(userClass); //class com.zmd.classTest.User
6,获取一个类实现了那些接口
Class[] getInterfaces(): 返回该 Class 对象对应类所实现的全部接口
//通过内查看实现了哪些接口 Class<?>[] interfaces = User.class.getInterfaces(); for (Class<?> interfaceClass : interfaces) { System.out.println(interfaceClass); }
7,获取一个类对应的父类的Class
Class getSuperclass():返回该Class对象对应类的超类的Class对象
//获取父类的Class Class<?> parentClass = studentClass.getSuperclass(); System.out.println(parentClass); //class java.lang.Object
8,获取对应类的修饰符、所在包、类名等基本信息。
- (1), int getModifiers(): 返回此类或接口的所有修饰符。修饰符由 public protected private final static abstract 等对应的常量组成。返回的整数应使用Modifier工具类的方法来解码,才可以获取真实的修饰符
- (2),Package getPackage(): 获取此类的包。
- (3),String getName(): 以字符串形式返回此 Class 对象所表示的类的名称。
- (4),String getSimpleName(): 以字符串形式返回此 Class 对象所表示的类的简称
获取修饰符:
Method runMethod = User.class.getDeclaredMethod("run"); //获取方法修饰符代号 int modifies = runMethod.getModifiers(); System.out.println(Modifier.isPublic(modifies)); //是否是public的 //true System.out.println(Modifier.isStatic(modifies)); //是否是static静态的//true System.out.println(Modifier.isAbstract(modifies));//是否是抽象的//false System.out.println(Modifier.isFinal(modifies)); //是否是final的//false
9,判断该类是否为接口、枚举、注解类型等。
- (1), boolean isAnnotation(): 返回此Class对象是否表示一个注解类型。
- (2), boolean isAnnotationPresent(Class annotationC ass) 判断此Class对象是否使用了某个Annotation修饰。
- (3), boolean isAnonymousClass(): 返回此Class对象是否是一个匿名类
- (4), boolean isArray(): 返回此Class对象是否表示一个数组类。
- (5), boolean isEnum(): 返回此Class对象是否表示一个枚举(由enum关键宇定义)。
- (6), boolean isInterface(): 返回此Class对象是否表示一个接口〈使用interface定义)。
- (7), boolean isInstance(Object obj): 判断obj是否是此Class对象的实例,该方法可以完全代替instanceof操作符。
posted on 2021-05-16 14:11 zhangmingda 阅读(656) 评论(0) 编辑 收藏 举报