Method
String str = "abcde";
Method methodCharAt = String.class.getMethod("charAt", int.class);
System.out.println(methodCharAt.invoke(str, new Object[]{2}));// str对象invole(调用)方法。new Object[]{2}(可以理解为创建一个Object类型的数组,数组中元素是(2这个整数)Object对象,可以自动拆箱成整数2)如果是调用静态方法,则先获得方法,再把str对象改成null。
数组的反射
// 具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。
int[] nums1 = newint[2];
int[] nums2 = newint[5];
System.out.println(nums1.getClass() == nums2.getClass());
不管是几维数组,父类都是Object.
Method用法例题: //写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法。
//我的方法
class MyDefineMain {
publicstaticvoid main(String[] args) {
System.out.println("我是自定义类的主方法" + args[0]);
}
}
publicclass Test {
publicstaticvoid main(String[] args) throws Exception {
Method mainMethod = MyDefineMain.class.getMethod("main", String[].class);
mainMethod.invoke(null, (Object) new String[] { "abc" });
}
}
//老师的方法
class DefineMain {
publicstaticvoid main(String[] args) {
System.out.println("我是自定义类的主方法" + args[0]);
}
}
publicclass Test {
publicstaticvoid main(String[] args) throws Exception {
// DefineMain.main(new String[]{"abc"});// 自定义方法之前是这样调用的
//在Eclipse运行的时候手动把自定义类的类的全名作为这个main方法的参数传进来
String str = args[0];// 如果没有传参数进来,则不能这么赋值
Method mainMethod = Class.forName(str).getMethod("main", String[].class);
//关于forName()方法:Class cls = Class.forName("java.lang.String");// 引号里指定类的全名
mainMethod.invoke(null, (Object) new String[] { "abc" });
// new String[] { "abc" }要强转为Object的原因??查阅API可知,
invoke的参数可以是一个个Object对象,或者Object数组。这时就会产生不明确性,因为
new String[] { "abc" }既可以当做一个obj对象,又可以当做objs数组。理由见下面举例
而如果是自定义数据类型,比如new int[] { 123 }就不需要强转,因为这就是一个Object子类对象。
// int[] nums = new int[] { 2, 3 };
// String[] strs = new String[] { "abc", "def" };
// Object[] obj=nums;//Error因为Object 数组中每个元素都是一个对象,而nums中的每个元素并不是对象
// Object obj = strs;
// Object[] objs = strs;// strs中的内容是字符串,而字符串又是一个个对象。这两句验证了上面要强转成Object的原因。
另外,关于数组变成集合再打印的小结
int[] nums = new int[] { 2, 3 };
int[][] nums2 = new int[][] { { 1, 3 }, { 2, 6 } };
String[] strs = new String[] { "abc", "def" };
Person[] ps = new Person[] { new Person(20, "zs"), new Person(30, "ls") };
System.out.println(Arrays.asList(nums));// [[I@1542a75]
System.out.println(Arrays.asList(nums2));// [[I@af993e, [I@75e4fc]
System.out.println(Arrays.asList(ps));//[cn.itcast.Person@c62c8,
//cn.itcast.Person@12940b3]
System.out.println(Arrays.asList(strs));// [abc, def]
综上,数组变成集合,打印的是数组中各个对象的地址值(如果没有重写toString()方法的话)
}
}
// 例题:如果一对象是数组,那打印出它的每个元素,如果不是,直接打印
publicstaticvoid main(String[] args) throws Exception {
String[] strs = new String[] { "abc", "def" };
printObject(strs);
}
publicstaticvoid printObject(Object obj) {
Class cls = obj.getClass();// 获得对象的字节码文件
if (cls.isArray()) {// 判断此字节码文件是否是数组对象
int len = Array.getLength(obj);
for (int i = 0; i < len; i++) {
System.out.println(Array.get(obj, i));
}
} else {
System.out.println(obj);
}
}
HashSet集合的注意事项。
// 当一个对象被存储进 hashset集合之后,就不能修改对象中参与哈希值计算的属性了
// 因为修改之后,当前对象虽然还在。但是已经修改了其在集合中的存储位置,
// 当你对该对象进行删除的时候,将返回找不到该对象的结果,从而可能会造成内存泄露
Collection coll = new HashSet();
Person p1 = new Person(20, "lisi");
Person p2 = new Person(30, "ww");
coll.add(p1);
coll.add(p2);
p1.name = "as";
System.out.println(coll.remove(p1));// false
System.out.println(p1.name);// as
System.out.println(p1.age);// 20
System.out.println(coll.size());// 2
框架的理解:我在写框架时,要调用你以后写的类。而我无法知道你的类名,
所以,无法在程序中new某个类的实例对象。就要用反射来做。