一、反射中的Constructor
Constructor类代表某个类中的一个构造方法
Constructor 翻译过来的意思是"构造函数",它是用来描述一个类中的构造函数的。JDK帮助文档的解释--->Constructor
提供关于类的单个构造方法的信息以及对它的访问权限。
现在我有一个MyConstructor类,用反射分别打印出1,2,3.
public class MyConstructor {// --------------------------------------1
public MyConstructor(){
System.out.println("1");
}
public MyConstructor(int i){//--------------------------------------2
System.out.println("2");
}
public MyConstructor(int i,String s){//---------------------------3
System.out.println("3");
}
}
下面我们现在打印出一个1
public static void main(String[] args) throws Exception{
//截的图是JDK帮助文档里面的解释
Constructor myConstructor1 = MyConstructor.class.getConstructor();//这里得到的是标记为1的构造函数(相关知识点方法的重载)
myConstructor1.newInstance();
//上面的2句话输出结果为1.
Constructor myConstructor1 = MyConstructor.class.getConstructor(int.class);//这里得到的是标记为2的构造函数(相关知识点方法的重载)
//开始由于受到反射invoke()的思想,并且没有看帮助文档对newInstance()的解释,然后我直接写了下面的语句
myConstructor1.newInstance(new MyConstructor());//new MyConstructor()我的意思是传带有myConstructor1的构造函数方法的对象给它调用(这里不懂的同学可以看帮 //助文档Method类中invoke()方法的解释),好嘛这里是我弄混淆了
写成这样也是错的myConstructor1.newInstance(int.class);
//输出结果为
//argument type mismatch翻译过来的意思是:参数类型不匹配
// 最后写成这样就对了
myConstructor1.newInstance(0);
//执行输出的结果为2.
//打印1和打印2都写出来了,想必大家打印出3就不难了。
Constructor myConstructor1 = MyConstructor.class.getConstructor(int.class,String.class);//这里得到的是标记为3的构造函数(相关知识点方法的重载)
myConstructor1.newInstance(0,"a");
//执行输出的结果为3
}
二、数组反射
在jdk帮助文档中的Class介绍有这样的话:
什么意思呢?意思就是说如果有2个数组对象,它们具有相同的元素类型和维数的话,那它们的class(在内存中的字节码)也是相同的。
示例代码一:
public static void main(String[] args){
int [] a1 = new int[3];
int [] a2 = new int[4];
int [][] a3 = new int[2][3];
String[] a4 = new String[3];
System.out.println(a1==a2);//类型相等,维度相等
//System.out.println(a1==a4);//类型不等,维度相等--------这句编译报错
//System.out.println(a1==a3);//类型相等,维度不等--------这句编译报错
}
输出为:false
咦~~~怎么会是false呢,明明类型相等,维度相等,那为什么还是false呢?后面突然发现a1 == a2比的是对象,它们的内容不相等,所以为false。最后改成下面的正确代码:
public static void main(String[] args){
int [] a1 = new int[3];
int [] a2 = new int[4];
int [][] a3 = new int[2][3];
String[] a4 = new String[3];
System.out.println(a1.getClass()==a2.getClass());//类型相等,维度相等
System.out.println(a1.getClass()==a4.getClass());//类型不等,维度相等
System.out.println(a1.getClass()==a3.getClass());//类型相等,维度不等
}
这里大家在看下面的结果前可以自己先想想
输出结果为:
true
false
false
在这里有个小插曲下面2张图大家对比下
图一:
图二:
细心的你一定发现了哈,二张图的内容都是一样的,毫无区别,那为什么图二中的内容有编译不通过的呢?
现在我只能告诉你图一的JDK是1.4的,而图二的JDK是1.6的,关于JDk1.5有兴趣的朋友可以改来试试哈,至于为什么会这样,具体原因我也说不出来,因为我不知道,嘿嘿~~~~(拿别人的回答来给大家参考参考吧------->“这是编译报错,你用的比以前的东西高级了,后面两个明显因为是类型都不对,答案是false的就直接编译就报错了再说明白点,编译器版本高了聪明了,觉得这种问题低级所以不想让你编译通过了”对这解释感觉神忽忽的--!)
好奇的人会尝试的运行这个代码:System.out.println(a1.getClass().getName());输入结果为:[I,什么意思呢?[:代表是数组,I:代表是int类型。与之相关的介绍在JDK帮助文档里面有解说。
System.out.println(a3.getClass().getName());//int [][] a3 = new int[2][3];
System.out.println(void.class.getName());
上面两句分别输出:
[[I
void
如果是String[][][][][] test = new String[1][2][3][4][5];会输出什么?
public static void main(String[] args){
int [] a1 = new int[3];
int [] a2 = new int[4];
int [][] a3 = new int[2][3];
String[] a4 = new String[3];
System.out.println(a1.getClass().getSuperclass().getName());//getSuperclass()得到父类的class
System.out.println(a4.getClass().getSuperclass().getName());
//这2句话输出分别为java.lang.Object和java.lang.Object(表明a1和a4的父类都一样)
//所以
Object aObj1 = a1;//里氏替换原则
Object aObj2 = a4;//里氏替换原则
//下面代码回报编译异常
Object[] aObj3 = a1;//int [] a1 = new int[3];理解为有一个int[]数组,里面装的是int类型,int类型不属于Object
Object[] aObj4 = a3;//int [][] a3 = new int[2][3];理解为有一个int[]数组,里面装的是int[]类型,int[]类型属于Object
Object[] aObj5 = a4;//String[] a4 = new String[3];理解为有一个String[]数组,里面装的是String类型,String类型属于Object
}
用反射的方式操作数组
我有一个方法public static void print(Object obj){},这方法是用来打印东西的方法,你传一个对象给我,我就给你打印,这时候问题出现了,你会不会传一个数组给我呢?答案是会的,但是我又怎么知道你传的是数组呢?这时候数组的反射有派上用场了
上代码:
/**
* 打印对象
* @param obj 你传来的任何对象,如果是数组,打印里面的每一个元素
*/
public static void printObject(Object obj){
Class clazz = obj.getClass();
//true:代表是数组,false:代表不是数组
if (clazz.isArray()) {
int len = Array.getLength(obj);
for (int i = 0; i < len; i++) {
System.out.println(Array.get(obj, i));
}
System.out.println("另一种获取的方法");
Object[] tempObj = (Object[]) obj;
for (Object object : tempObj) {
System.out.println(object);
}
}else{
System.out.println(obj);
}
}
public static void main(String[] args){
printObject(a4);
printObject("hahaha");
}
输出结果:
a
b
c
另一种获取的方法
a
b
c
hahaha
有一个Object[] a = new Object[]{"a",1};这时候您是说不清这个a是什么类型的,说是int它里面有String,说是String它里面有int,但是可以知道a[0]是什么类型的,a[1]是什么类型的,a[0].getClass().getName();