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 类型(booleanbytecharshortintlongfloat 和 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();
        }
        
    }
获取Class对象的三种方法
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('男');
    }
    
View Code

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)    收藏  举报

导航