黑马程序员技术交流社区
标题:
一个关于反射的入门程序,求大神进来指导
[打印本页]
作者:
王责彬
时间:
2014-8-25 23:10
标题:
一个关于反射的入门程序,求大神进来指导
import java.lang.reflect.Constructor;
import java.lang.reflect.*;
public class Example_01 {
String s;
int i, i2, i3;
private Example_01() {
}
protected Example_01(String s, int i) {
this.s = s;
this.i = i;
}
public Example_01(String... strings) throws NumberFormatException {
if (0 < strings.length)
i = Integer.valueOf(strings[0]);
if (1 < strings.length)
i2 = Integer.valueOf(strings[1]);
if (2 < strings.length)
i3 = Integer.valueOf(strings[2]);
}
public void print() {
System.out.println("s=" + s);
System.out.println("i=" + i);
System.out.println("i2=" + i2);
System.out.println("i3=" + i3);
}
public static void main(String[] args) {
Example_01 example = new Example_01("10", "20", "30");
Class<? extends Example_01> exampleC = example.getClass();
Constructor[] declaredConstructors = exampleC.getDeclaredConstructors();
for (int i = 0; i < declaredConstructors.length; i++) {
Constructor<?> constructor = declaredConstructors
;
System.out.println("查看是否允许带有可变数量的参数:" + constructor.isVarArgs());
System.out.println("该构造方法的入口参数类型依次为:");
Class[] parameterTypes = constructor.getParameterTypes();
for (int j = 0; j < parameterTypes.length; j++) {
System.out.println(" " + parameterTypes[j]);
}
System.out.println("该构造方法可能抛出的异常类型为:");
Class[] exceptionTypes = constructor.getExceptionTypes();
for (int j = 0; j < exceptionTypes.length; j++) {
System.out.println(" " + exceptionTypes[j]);
}
Example_01 example2 = null;
while (example2 == null) {
try {
if (i == 2)
example2 = (Example_01) constructor.newInstance();
else if (i == 1)
example2 = (Example_01) constructor.newInstance("7", 5);
else {
Object[] parameters = new Object[] { new String[] {
"100", "200", "300" } };
example2 = (Example_01) constructor
.newInstance(parameters);
}
} catch (Exception e) {
System.out.println("在创建对象时抛出异常,下面执行setAccessible()方法");
constructor.setAccessible(true);
}
}
if(example2!=null){
example2.print();
System.out.println();
}
}
}
}
运行结果:
查看是否允许带有可变数量的参数:true
该构造方法的入口参数类型依次为:
class [Ljava.lang.String;
该构造方法可能抛出的异常类型为:
class java.lang.NumberFormatException
s=null
i=100
i2=200
i3=300
查看是否允许带有可变数量的参数:false
该构造方法的入口参数类型依次为:
class java.lang.String
int
该构造方法可能抛出的异常类型为:
s=7
i=5
i2=0
i3=0
查看是否允许带有可变数量的参数:false
该构造方法的入口参数类型依次为:
该构造方法可能抛出的异常类型为:
s=null
i=0
i2=0
i3=0
大神讲讲这个程序是怎么运行的?步骤。先行谢过
作者:
hejinzhong
时间:
2014-8-26 09:59
不好好看视频,有点蛋疼
import java.lang.reflect.*;
public class Example_01 {
/*
* 定义4个成员变量
*/
String s;
int i, i2, i3;
// 无参构造函数
@SuppressWarnings("unused")
private Example_01() {
}
// 参数类型为 String和int 的构造函数
protected Example_01(String s, int i) {
this.s = s;
this.i = i;
}
// String类型可变参数的构造函数,且抛出异常
public Example_01(String... strings) throws NumberFormatException {
/*
* 下面是获取相应位置的参数
*/
if (0 < strings.length)
i = Integer.valueOf(strings[0]);
if (1 < strings.length)
i2 = Integer.valueOf(strings[1]);
if (2 < strings.length)
i3 = Integer.valueOf(strings[2]);
}
// 输出成员变量值的函数
public void print() {
System.out.println("s=" + s);
System.out.println("i=" + i);
System.out.println("i2=" + i2);
System.out.println("i3=" + i3);
}
// 主函数
public static void main(String[] args) {
// 创建一个Example_01的对象,且调用的是可变参数构造函数
Example_01 example = new Example_01("10", "20", "30");
/*
* 通过example对象获取Example_01的字节码文件,目的是为了下面反射用
* 因为反射的前提就是拿到需要反射类的Class
* 这里泛型限定可以不管
*/
Class<? extends Example_01> exampleC = example.getClass();
/*
* 得到Example_01中的所有方法,这里用的是Declared,可以获取任何类型
* 包括私有和保护的(如果有的话)
*/
Constructor[] declaredConstructors = exampleC.getDeclaredConstructors();
// 遍历所有的构造函数
for (int i = 0; i < declaredConstructors.length; i++) {
// 得到相应的构造函数,并对其进行操作
Constructor<?> constructor = declaredConstructors[i];
// 用isVarArgs方法判断构造函数时候有可变参数,返回类型Boolean,并打印
System.out.println("查看是否允许带有可变数量的参数:" + constructor.isVarArgs());
/*
* getParameterTypes得到构造函数的参数类型,由于可能不止一个参数,所以返回类型为数组
* 并通过for循环打印出各参数类型
*/
System.out.println("该构造方法的入口参数类型依次为:");
Class[] parameterTypes = constructor.getParameterTypes();
for (int j = 0; j < parameterTypes.length; j++) {
System.out.println(" " + parameterTypes[j]);
}
/*
* getExceptionTypes得到构造函数抛出异常类型,同样由于抛出异常
* 可能不止一个所以返回的也是数组类型
* 也是通过for循环打印所有异常
*/
System.out.println("该构造方法可能抛出的异常类型为:");
Class[] exceptionTypes = constructor.getExceptionTypes();
for (int j = 0; j < exceptionTypes.length; j++) {
System.out.println(" " + exceptionTypes[j]);
}
/*
* 下面是建立相应构造函数的实例对象
* 这里需要注意的是,上面在获取构造函数时,返回数组中的元素没有排序,也没有任何特定的顺序。
* 所以是按照上面遍历输出结果决定的个构造函数的顺序 这里的i判断,
* 对应上面相应的输出,可以看你的输出结果
*/
Example_01 example2 = null;
while (example2 == null) {
try {
if (i == 2)
/*
* 这个空参构造函数,没有为任何成员变量赋值,所以输出都为其初始值null或0
*/
example2 = (Example_01) constructor.newInstance();
else if (i == 1)
/*
* 这个固定参数的构造函数中,为成员变量s和i分别赋值,
* 且值的 大小为构造时传入值,这里分别为7和5
* 其他为默认值
*/
example2 = (Example_01) constructor.newInstance("7", 5);
else {
/*
* 这里是可变参数列表,根据上面的构造函数可以看出,他分别为i,i2,i3赋值
* 这里分别为100,200,300 s还是默认的null
*/
Object[] parameters = new Object[] { new String[] {
"100", "200", "300" } };
example2 = (Example_01) constructor
.newInstance(parameters);
}
} catch (Exception e) {
System.out.println("在创建对象时抛出异常,下面执行setAccessible()方法");
constructor.setAccessible(true);
}
}
// 这里是调用print方法,打印所有成员变量的值,上面已经说了值为多少
if (example2 != null) {
example2.print();
System.out.println();
}
}
}
}
复制代码
作者:
ZHENGYUNJUN
时间:
2017-9-6 14:58
hejinzhong 发表于 2014-8-26 09:59
为什么直接是从参数多的执行的?
作者:
牢记圣光
时间:
2017-11-16 15:36
ZHENGYUNJUN 发表于 2017-9-6 14:58
为什么直接是从参数多的执行的?
我也想知道啊!
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2