黑马程序员——反射调用main方法和数组Class及数组参数

  ------- <"http://www.itheima.com"">android培训<"http://www.itheima.com" java培训、期待与您交流! ----------


public class ReflectTest 
{
public static void main(String[]args) throws Exception
{

//调用TestArguments类中的main方法。

// TestArguments.mian(new String[]{"111","222","333"});
 
 
//用反射的方法调用
// Object invoke(Object obj, Object... args) 
 
//将printObject类的完整类名的字符串传到args[]中,并获取TestArguments类的完整类名
String startingClassName=args[0];
Method mainMethod=Class.forName(startingClassName).getMethod("main",String[].class);
// mainMethod.invoke(null,new String[]{"111","222","333"});
//要从类型 Method 中调用 varargs 方法 invoke(Object, Object...),应该将类型为 String[] 的参
// 数显式地强制转换为 Object[]。对于 varargs 调用来说,也可以将其强制转换为 Object
 
mainMethod.invoke(null,new Object[]{new String[]{"111","222","333"}});
//main方法是静态的,所以不需要对象。即:null.
/*启动java程序的main方法的参数是一个字符串数组,即:public static void main(String[]args)
 * 通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?按JKD1.5d 语法,整个数组是一个
 * 参数,而按JKD1.4的语法,数组中的每个元素对应一个参数,当把一个字符串数组作为参数传递给invoke方法时
 * javac 会到底按照哪种语法进行处理呢?JDK1.5肯定要兼容JDK1.4的语法,会按照JDK1,4的语法进行处理
 * 即:把数组打散成为若干个单独的参数。所以,在给main方法传递参数时,不能使用代码
 * mainMethod.invoke(null,new String[]{"xxx"},javac只把它当做jdk1,4的语法进行理解,而不把他当做jdk1.5
 * 的语法理解,因此会出现参数类型不对的问题。
 * 解决方法:
 * 1.mainMethod.invoke(null,new Object[]{new String[]{"xxx"}});
 * 2.mainMethod.invoke(null,(Object)new String[]{"xxx"});
 * 上面两个方法:
 * 1是说,你要拆数组,那好我就把数组在包一个数组,你拆外面的不影响里面的。
 * 2是说,它不是要把数组拆开吗,那我就把这个数组变成个对象,相当于告诉
 * 编译器说,我这是个对象,不是数组,你不要拆。
 * */
 
//数组的Class
/*基本类型的一维数组可以被当做Object类型使用,不能当做Object[]类型使用
 * 非基本类型的数组(包括二维数组)即可以当做Object类型使用,也可以当做
 * Object[]类型使用。
 * 
 * Arrays.asList()方法处理int[]和String[]时有差异:就是把数组当做参数传递时,会进行拆包,把数组中的每一个
 * 元素都拆成一个参数传递。造成的。即:list直接是对象,int类型数组只能整体当做一个对象。String【】每一个元素
 * 都可以拆成一个对象。
 * 即:当把数组作为参数传递时:JDK1.5肯定要兼容JDK1.4的语法,会按照JDK1,4的语法进行处理
 * 即:把数组打散成为若干个单独的参数。
 * */
// int []a1=new int[3]{1,2,3};如果提供了数组初始化操作,则不能定义维表达式
int[]a1=new int[]{1,2,3};
int []a2=new int[4];
int [][]a3=new int[2][3];
//String []a4=new String[3];
String[]a4=new String[]{"a","b","c"};
System.out.println(a4+"::::");
System.out.println(a1.getClass()==a2.getClass());//true
//System.out.println(a1.getClass()==a4.getClass());//false,类型不兼容,编译不通过
//dSystem.out.println(a1.getClass()==a3.getClass());//false,类型不兼容,编译不通过
System.out.println(a1.getClass().getName()+"::"+a2.getClass().getName());//[I::[I

//打印a1,a3,a4的父类的名字。
System.out.println(a1.getClass().getSuperclass().getName());//Object
System.out.println(a3.getClass().getSuperclass().getName());//Object
System.out.println(a4.getClass().getSuperclass().getName());//Object

Object aObj1=a1;//对的。a1是个数组,数组是Object的子类
Object aObj2=a4;//对的。a4是额数组,数组是Object的子类
//Object[] aObj3=a1;//不对,编译通过不了。Object类型的数组,只能装对象。
//而a1是int类型 的数组,里面装的是int整数,不是对象。
Object[] aObj4=a3;//对,a3数组里装的是一个数组,是Object的子类
Object[] aObj5=a4;//对,a4装的是String,String是Object的子类。


System.out.println("1:::"+Arrays.toString(a1));//1:::[1, 2, 3]
System.out.println("2:::"+Arrays.asList(a1));//2:::[[I@f47bf5]
System.out.println("3:::"+Arrays.asList(a4));//3:::[a, b, c]
/*1,2,3相比是为什么呢?1是toString不用说了。2和3用的是asList,
* 即:将数组装到集合里。打印集合打印的集合中的元素。
* 为什么2和3不一样呢?
* 因为JDk1.4中还没有可变参数,asList方法接收的是Object[]obj,即所有类型的数组,list只能装对象。
* 所以2在JDK1.4中是处理不了的。Object类型的数组,只能装对象。
* 而a1是int类型 的数组,里面装的是int整数,不是对象。所以将整个数组作为对象存入List中。
* 而3中的list集合中装的是三个元素:分别是“a","b","c".
* 而JDK1.5之后出现了可变参数和泛型,asList的参数类型由Object[]obj,变成了T...a
* 即:指定类型(泛型)的不管长度多少的数组,都能接收。如果你的数组中的元素类型是对象,
* 就把他们分别作为一个对象,存入到List中,如果你的数组中装的不是对象,而是基本类型数据,
* 那就把整个数组作为对象存入List中。
* 即:
* */

//Object ob=null;
//printObject(ob);


}
private static void printObject(Object ob)
{//用反射判断这个对象是否是数组。
Class cla=ob.getClass();
if(cla.isArray())
{
int len=Array.getLength(ob);
for(int i=0;i<len;i++)
{
System.out.println(Array.get(ob,i));
}
}
else
System.out.println(ob);
}

private static void changeStringValue(Object obj)throws Exception
{
Field[] fields=obj.getClass().getFields();
for(Field field:fields)
{
//if(field.getType().equals(String.class))
//对于字节码的比较用==,用equals也能比,但不科学。因为字节码只有一份,就相当于说,看他指向的是整形
//类字节码,还是字符串型的字节码
if(field.getType()==String.class)
{
String oldValue=(String)field.get(obj);
String newValue=oldValue.replace('b', 'a');
field.set(obj,newValue);
}
}
}
}
class TestArguments
{
public static void main(String[]args)
//在编译时给主方法传递一个参数,该参数是TestArguments类的完整类名的字符串。传递给数组String[]args
//就相当于主函数的参数中有个元素:即数组的0角标上有个字符串元素。
//args[o]=cn.itcast.day1.TestArguments


{
for(String arg:args)
{
System.out.println(arg);
}
}

}

------- "http://www.itheima.com>android培训<"http://www.itheima.com">java培训<、期待与您交流! ----------


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值