Java基础--Java反射机制
参照
java 反射详解 https://blog.csdn.net/yongjian1092/article/details/7364451
Java基础之—反射(非常重要) https://blog.csdn.net/sinat_38259539/article/details/71799078
Class 类 的更多API可以查询:
中文网址:http://tool.oschina.net/apidocs/apidoc?api=jdk-zh
英文网址:http://tool.oschina.net/apidocs/apidoc?api=jdk_7u4
一、什么是JAVA的反射机制
java运行期间能够对任意一个对象或类,都能够操作它的属性和方法。
二、java reflection APIs(java.lang.reflect )
java.lang.reflect
Member: 源码注释:Member is an interface that reflects identifying information about a single member (a field or a method) or a constructor.
Member是反映成员(属性和方法)或构造函数信息的接口。
public interface Member {}
AccessibleObject :
public class AccessibleObject implements AnnotatedElement{}
AccessibleObject 类是 Field、Method 和 Constructor 对象的基类。
它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。
对于公共成员、默认(打包)访问成员、受保护成员和私有成员,在分别使用 Field、Method 或 Constructor 对象来设置或获取字段、调用方法,或者创建和初始化类的新实例的时候,会执行访问检查。
Modifier:
public class Modifier
源码(mod & PUBLIC) != 0未理解。
Field :
public final class Field extends AccessibleObject implements Member {}
Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。
Method:
public final class Method extends Executable {}
Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息
Constructor:
public final class Constructor<T> extends Executable {}
Constructor 提供关于类的单个构造方法的信息以及对它的访问权限。
Array:
public final class Array {}
Array 类提供了动态创建和访问 Java 数组的方法。
Proxy:
public class Proxy implements java.io.Serializable {
Proxy提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
三、JAVA反射机制提供了什么功能
在使用Java的反射功能时,基本首先都要获取类的Class对象,再通过Class对象获取其他的对象。
1、获得class对象
2、创建实例
3、操作实例的方法和属性
Class类:
java.lang.Class
public final class Class<T> implements java.io.Serializable,
GenericDeclaration,
Type,
AnnotatedElement {}
类型参数:T- 由此Class对象建模的类的类型。例如,String.class的类型是Class<String>。如果将被建模的类未知,则使用Class<?>。
Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。
每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。
基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。
1、获取类的Class对象三种方法 Class
①Object.getClass() ,一般不用,有实例了为啥还要获得Class对象
②每种类型都有.class属性,一般不用,导入类的包,依赖太强.
③Class静态方法forName(),参数需要指定包名,常用.
package fanshe; /** * 获取Class对象的三种方式 * 1 Object ——> getClass(); * 2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性 * 3 通过Class类的静态方法:forName(String className)(常用) * */ public class Fanshe { public static void main(String[] args) { //第一种方式获取Class对象 Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。 Class stuClass = stu1.getClass();//获取Class对象 System.out.println(stuClass.getName()); //第二种方式获取Class对象 Class stuClass2 = Student.class; System.out.println(stuClass == stuClass2);//判断第一种方式获取的Class对象和第二种方式获取的是否是同一个 //第三种方式获取Class对象 try { Class stuClass3 = Class.forName("fanshe.Student");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名 System.out.println(stuClass3 == stuClass2);//判断三种方式是否获取的是同一个Class对象 } catch (ClassNotFoundException e) { e.printStackTrace(); } }
2、Constructor 获取构造函数
1.获取构造方法:
1).批量的方法:
public Constructor[] getConstructors():所有"公有的"构造方法
public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
2).获取单个的方法,并调用:
public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;
package fanshe; import java.lang.reflect.Constructor; /* * 通过Class对象可以获取某个类中的:构造方法、成员变量、成员方法;并访问成员; * * 1.获取构造方法: * 1).批量的方法: * public Constructor[] getConstructors():所有"公有的"构造方法 public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有) * 2).获取单个的方法,并调用: * public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法: * public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有; * * 调用构造方法: * Constructor-->newInstance(Object... initargs) */ public class Constructors { public static void main(String[] args) throws Exception { //1.加载Class对象 Class clazz = Class.forName("fanshe.Student"); //2.获取所有公有构造方法 System.out.println("**********************所有公有构造方法*********************************"); Constructor[] conArray = clazz.getConstructors(); for(Constructor c : conArray){ System.out.println(c); } System.out.println("************所有的构造方法(包括:私有、受保护、默认、公有)***************"); conArray = clazz.getDeclaredConstructors(); for(Constructor c : conArray){ System.out.println(c); } System.out.println("*****************获取公有、无参的构造方法*******************************"); Constructor con = clazz.getConstructor(null); //1>、因为是无参的构造方法所以类型是一个null,不写也可以:这里需要的是一个参数的类型,切记是类型 //2>、返回的是描述这个无参构造函数的类对象。 System.out.println("con = " + con); //调用构造方法 Object obj = con.newInstance(); // System.out.println("obj = " + obj); // Student stu = (Student)obj; System.out.println("******************获取私有构造方法,并调用*******************************"); con = clazz.getDeclaredConstructor(char.class); System.out.println(con); //调用构造方法 con.setAccessible(true);//暴力访问(忽略掉访问修饰符) obj = con.newInstance('男'); }
3 获取成员变量并调用 Field
获取成员变量并调用:
*
* 1.批量的
* 1).Field[] getFields():获取所有的(包含继承的)"公有字段"
* 2).Field[] getDeclaredFields():获取所有字段(不包含继承的),包括:私有、受保护、默认、公有;
* 2.获取单个的:
* 1).public Field getField(String fieldName):获取某个"公有的"字段;
* 2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)
*
* 设置字段的值:
* Field --> public void set(Object obj,Object value):
* 参数说明:
* 1.obj:要设置的字段所在的对象;
4、获取成员方法并调用
* 获取成员方法并调用:
*
* 1.批量的:
* public Method[] getMethods():获取所有"公有方法";(包含了父类的方法也包含Object类)
* public Method[] getDeclaredMethods():获取所有的成员方法,包括私有的(不包括继承的)
* 2.获取单个的:
* public Method getMethod(String name,Class<?>... parameterTypes):
* 参数:
* name : 方法名;
* Class ... : 形参的Class类型对象
* public Method getDeclaredMethod(String name,Class<?>... parameterTypes)
*
* 调用方法:
* Method --> public Object invoke(Object obj,Object... args):
* 参数说明:
* obj : 要调用方法的对象;
* args:调用方式时所传递的实参;
***************************************************************************************************************************************
Class APIs
所在包:java.lang
public final class Class<T> implements java.io.Serializable,
GenericDeclaration,
Type,
AnnotatedElement {}
public T newInstance(): 根据Class对象创建类实例 class.newInstance();
public String getName() : 基本数据类型或void,返回本身;类或接口类型,返回包名.类或接口名
public String getSimpleName(): 返回类或接口名
posted on 2019-04-24 08:56 helloJava小白 阅读(72) 评论(0) 收藏 举报
浙公网安备 33010602011771号