详述反射中的构造方法

反射系列传送门

              如何获取Class类对象

              详述反射中的构造方法(本篇)

              详述反射中的普通方法

              详述反射中的属性


什么是反射?

Java反射(Reflection)是一种新的操作类中成员变量构造方法普通方法的机制

为了实现对成员变量、构造方法和普通方法的操作,我们需要借助Java自身提供的java.lang包下的Class类和java.lang.reflect包下的反射API 。

在上篇博客(如何获取Class类对象)中,已经介绍如何获取Class类对象,而Class类的实例化对象其实就是反射机制的实现入口,本篇博客将会详细介绍反射中的构造方法。


现有学生类如下(用于本篇博客的实例证明):

public class Student {
 
    String name;
    Integer id;
	
    public Student() {
		
    }
    public Student(String name) {
	this.name=name;
    }
    private Student(Integer id) {//Integer为int类型的包装类
        this.id=id;
    }
    public void sleep() {
	System.out.println(name+" go to sleep ");
    }
    public void say() {
	System.out.println("学号为:"+id);
    }
}

 

使用反射获取构造方法的实例对象

借助Class类某些方法可以获取对应类中声明的构造方法的实例化对象。

实例化构造方法的对象有四种方法,可以分为两类:适用于public修饰的构造方法和不区分访问权限。

第一类:适用于public修饰的构造方法

1、使用Class类实例化对象.getConstructor()获取无参构造方法的实例化对象

package test;

import java.lang.reflect.Constructor;

public class Test {

    public static void main(String[] args) {
	Class clazz=null;
	clazz = Student.class;//通过使用类名.class获取Class类实例
        try {
	    Constructor constructor = clazz.getConstructor();//获取无参构造方法的实例化对象
	    System.out.println(constructor.getName());
	} catch (Exception e) {
	    e.printStackTrace();
	}
    }
}

2、使用Class类实例化对象.getConstructor(Class<?>... parameterTypes)获取有参构造方法的实例化对象

package test;

import java.lang.reflect.Constructor;

public class Test {

    public static void main(String[] args) {
	Class clazz=null;
	clazz = Student.class;//通过使用类名.class获取Class类实例
        try {
	    Constructor constructor = clazz.getConstructor(String.class);//获取有参构造方法的实例化对象
	    System.out.println(constructor.getName());
	} catch (Exception e) {
	    e.printStackTrace();
	}
    }
}

 第二类:不区分访问权限

3、使用Class类实例化对象.getDeclaredConstructor()获取无参构造方法的实例化对象

package test;

import java.lang.reflect.Constructor;

public class Test {

    public static void main(String[] args) {
	Class clazz=null;
	clazz = Student.class;//通过使用类名.class获取Class类实例
        try {
	    Constructor constructor = clazz.getDeclaredConstructor();//获取无参构造方法的实例化对象
	    System.out.println(constructor.getName());
	} catch (Exception e) {
	    e.printStackTrace();
	}
    }
}

 4、使用Class类实例化对象.getDeclaredConstructor(Class<?>... parameterTypes)获取有参构造方法的实例化对象

注意:如果方法参数的数据类型为基本数据类型,则parameterType应为基本数据类型包装类.TYPE;如果方法参数的数据类型为基本数据类型包装类,则的数据类型应为包装类.class

package test;

import java.lang.reflect.Constructor;

public class Test {

    public static void main(String[] args) {
	Class clazz=null;
	clazz = Student.class;//通过使用类名.class获取Class类实例
        try {
	    Constructor constructor = clazz.getDeclaredConstructor(Integer.class);//获取有参构造方法的实例化对象
	    System.out.println(constructor.getName());
	} catch (Exception e) {
	    e.printStackTrace();
	}
    }
}

 

使用反射获取构造方法的属性

1、获取构造方法所在的类:Class<T> getDeclaringClass()

该方法返回声明Constructor对象对应构造方法的类的Class对象。

package test;

import java.lang.reflect.Constructor;

public class Test {

    public static void main(String[] args) {
	Class clazz=null;
	clazz = Student.class;//通过使用类名.class获取Class类实例
        try {
	    Constructor constructor = clazz.getDeclaredConstructor(String name);//获取有参构造方法的实例化对象
            clazz = constructor.getDeclaringClass();//获取构造方法所在类的Class对象
	    System.out.println(constructor.getName());//打印构造方法所在类的Class对象的类名
	} catch (Exception e) {
	    e.printStackTrace();
	}
    }
}

2、获取构造方法访问控制符:int getModifiers()

该方法以整数形式返回Constructor对象表示的构造函数的修饰符。

package test;

import java.lang.reflect.Constructor;

public class Test {

    public static void main(String[] args) {
	Class clazz=null;
	clazz = Student.class;
        try {
	    Constructor constructor = clazz.getDeclaredConstructor(String name);
            int mod = constructor.getModifiers();//获取以整数形式表示的访问控制符
	    String result  = Modifier.toString(mod);//将访问控制符从整数类型变为字符串类型
	    System.out.println(result);
	} catch (Exception e) {
	    e.printStackTrace();
	}
    }
}

3、获取构造方法的名字:String getName()

该方法以字符串形式返回Constructor对象所表示得构造方法的名称

package test;

import java.lang.reflect.Constructor;

public class Test {

    public static void main(String[] args) {
	Class clazz=null;
	clazz = Student.class;
        try {
	    Constructor constructor = clazz.getDeclaredConstructor(String name);
            System.out.println(constructor.getName());
	} catch (Exception e) {
	    e.printStackTrace();
	}
    }
}

4、获取构造方法参数列表:Class<?>[ ] getParameterTypes()

该方法返回由Constructor对象所表示的构造方法的形参类型对应Class对象组成的数组此 。如果构造方法没有参数,则数组长度为0

package test;

import java.lang.reflect.Constructor;

public class Test {

    public static void main(String[] args) {
	Class clazz=null;
	clazz = Student.class;
        try {
	    Constructor constructor = clazz.getDeclaredConstructor(String name);
            Class [] clazzs = constructor.getParameterTypes();//获取构造方法的参数列表
	    for (Class zz : clazzs) {//使用加强循环遍历参数列表
	        System.out.println(zz.getName());//打印参数类型
	    }
	} catch (Exception e) {
	    e.printStackTrace();
	}
    }
}

 

使用反射调用构造方法

使用newInstance(Object... initargs)创建声明该构造方法的新(上转型)对象。

initargs为传入该构造方法中的参数,如果该构造方法没有参数,则可设定为null或一个长度为0的数组。

package test;

import java.lang.reflect.Constructor;

public class Test3 {
    public static void main(String[] args) {
    Class clazz = Student.class;
        try {
	    Constructor constructor = clazz.getConstructor(String.class);
	    Object object = constructor.newInstance("Tom");//生成可以调用构造方法的上转型对象
	    Student stu = (Student)object;//对象下转型
	    stu.sleep();//调用方法
	} catch (Exception e) {
	    e.printStackTrace();
	}	
    }
}

如果构造方法使用private修饰那么就需要使用getDeclaredConstructor()方法创建构造方法对象,并且需要使用构造方法对象.setAccessible(boolean flag)方法,设定调用构造函数时忽略访问权限的影响(true表示忽略,false表示不忽略)

package test;

import java.lang.reflect.Constructor;

public class Test3 {
    public static void main(String[] args) {
    Class clazz = Student.class;
        try {
	    Constructor constructor = clazz.getDeclaredConstructor(Integer.class);
	    constructor.setAccessible(true);
            Object object = constructor.newInstance(2019111);//生成可以调用构造方法的上转型对象
	    Student stu = (Student)object;//对象下转型
	    stu.say();//调用方法
	} catch (Exception e) {
	    e.printStackTrace();
	}	
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值