java 编程基础 Class对象 反射 :获取类的构造方法,方法,成员变量,内部类,外部类,父类,实现的接口,修饰符等...
类 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,获取内部类:
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<?>[] interfaces = User.class.getInterfaces();
for (Class<?> interfaceClass : interfaces) {
System.out.println(interfaceClass);
}
7,获取一个类对应的父类的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操作符。
java 编程基础 Class对象 反射 :获取类的构造方法,方法,成员变量,内部类,外部类,父类,实现的接口,修饰符等...的更多相关文章
- java 编程基础 Class对象 反射 :参数反射
方法参数反射 Java8在java.lang.reflect包下新增了Executable抽象基类,该对象代表可执行的类成员,该类派生了Constructor和Method两个子类.Executabl ...
- java 编程基础 Class对象 反射:动态代理 和AOP:java.lang.reflect.Proxy:(Proxy.newProxyInstance(newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h))
为什么我们使用动态代理 静态代理会让类变多了,多了代理类,工作量变大了,且不易扩展.比如我们上节课的例子,要实现不同的扩展方法就要编写不同的代理类,非常麻烦. Proxy类的使用规则 Proxy提 ...
- java 编程基础 Class对象 反射 :数组操作java.lang.reflect.Array类
java.lang.reflect包下还提供了Array类 java.lang.reflect包下还提供了Array类,Array对象可以代表所有的数组.程序可以通过使 Array 来动态地创建数组, ...
- java 编程基础 Class对象 反射:代理模式和静态代理
生活中的代理 类(对象)代理模式 代理模式是面向对象编程中比较常见的设计模式. 1. 用户只关心接口功能,而不在乎谁提供了功能.上图中接口是 Subject 2. 接口真正实现者是上图的 RealSu ...
- java中的反射机制,以及如何通过反射获取一个类的构造方法 ,成员变量,方法,详细。。
首先先说一下类的加载,流程.只有明确了类这个对象的存在才可以更好的理解反射的原因,以及反射的机制. 一. 类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三 ...
- C#通过反射获取类中的方法和参数个数,反射调用方法带参数
using System; using System.Reflection; namespace ConsoleApp2 { class Program { static void Main(stri ...
- Java反射学习-1 - 反射获取类的属性,方法,构造器
新建一个Person类 package cn.tx.reflect; /** * 注解初步了解 * @author Administrator * */ public class Person { p ...
- Java反射获取类和对象信息全解析
反射可以解决在编译时无法预知对象和类是属于那个类的,要根据程序运行时的信息才能知道该对象和类的信息的问题. 在两个人协作开发时,你只要知道对方的类名就可以进行初步的开发了. 获取类对象 Class.f ...
- java 编程基础 反射方式获取泛型的类型Fileld.getGenericType() 或Method.getGenericParameterTypes(); (ParameterizedType) ;getActualTypeArguments()
引言 自从JDK5以后,Java Class类增加了泛型功能,从而允许使用泛型来限制Class类,例如,String.class的类型实际上是 Class 如果 Class 对应的类暂时未知,则使 C ...
随机推荐
- spring-整合es
spring-整合es 导入pom <?xml version="1.0" encoding="UTF-8"?> <project xmln ...
- Python之阶乘代码
#coding=utf-8 while True: num = int(input("请输入要阶乘的正整数数字,按负数退出:")) jiec=1 if nu ...
- 群晖ping自动关机
因为学校宿舍环境的原因,每天早上10点左右宿管可能会来检查内务情况,然后一定会关闭电闸,就导致如果我的nas在10点半时开机的话用的是UPS的电源,直接导致UPS电量耗竭,而我又不可能一直去观察宿舍有 ...
- 洛谷 P3994 高速公路(斜率优化)
题目链接 题意:给出一棵树,\(1\) 号点为根,边上有边权. 每个点有两个参数 \(p_i,q_i\) 如果你想从 \(i\) 号点到与其距离为 \(d\) 的 \(j\) 号点,那么你需花费 \( ...
- Atcoder Regular Contest 061 D - Card Game for Three(组合数学)
洛谷题面传送门 & Atcoder 题面传送门 首先考虑合法的排列长什么样,我们考虑将每次操作者的编号记录下来形成一个序列(第一次 A 操作不计入序列),那么显然这个序列中必须恰好含有 \(n ...
- Redis高并发处理常见问题及解决方案
1. 大型电商系统高流量系统设计 场景: 大量电商系统每天要处理上亿请求,其中大量请求来自商品访问.下单.商品的详情是时刻变化,由于请求量过大,不会频繁去服务端获取商品信息,导致服务器压力极大.需要用 ...
- miRAN 分析以及mRNA分析
一些参考资料 http://www.360doc.com/content/17/0528/22/19913717_658086490.shtml https://www.cnblogs.com/tri ...
- C语言 自定义函数按行读入文件
在之前的博客中 https://www.cnblogs.com/mmtinfo/p/13036039.html 读取一行的getline()函数是GNU 的扩展函数. 这里用自定义函数实现这个功能,从 ...
- jumpserver——脚本安装
CentOS Linux release 7.7.1908 (Core) 3.10.0-1062.4.1.el7.x86_64 Initialize(){ yum update -y systemct ...
- Linux-各种姿势(less\vi等)打开各种类型的文件(txt/csv/xlsx等)出现不能打开(全乱码、部分乱码、二进制文件等)的问题
(一)linux各种中文乱码解决办法整理 远程登录服务器用vim在终端下编辑查看文件经常会遇见各种中文乱码问题. 做如下设置可基本解决vim中文乱码问题,首先查看系统对中文的支持locale -a | ...