A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© のソ夏末 中级黑马   /  2014-4-17 15:48  /  787 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 のソ夏末 于 2014-4-17 15:53 编辑

下面的代码主要是针对反射方面的诸多知识点进行强化巩固,用我们非常熟悉的Student类引出反射机制,意在将反射的方方面面集中在一个类中进行解释说明,并由此产生一些疑问。希望各位大牛同学能够帮我解答一下!
  1. package cn.itcast.day1;

  2. public class Student
  3. {
  4.         private String name = "zhangsan";
  5.         private int age = 26;
  6.         private String school ="fudandaxue";
  7.         public void shout()
  8.         {
  9.                 System.out.println("name: "+name+",age: "+age+",school: "+school);
  10.         }
  11.         private void speak()
  12.         {
  13.                 System.out.println("Hello World!");
  14.         }
  15.         public Student()
  16.         {        
  17.         }
  18.         public Student(String name, int age) {
  19.                 this.name = name;
  20.                 this.age = age;
  21.         }
  22.         public Student(String name, int age, String school) {
  23.                 this(name,age);
  24.                 this.school = school;
  25.         }
  26.         public String toString() {
  27.                 return "Student [name=" + name + ", age=" + age + ", school=" + school + "]";
  28.         }
  29. }
  30. class TestStudent
  31. {
  32.         public static void main(String[] args)
  33.         {               
  34.                 Student stu = new Student("zhaohongchun",26,"fudandaxue");
  35.                 stu.shout();
  36.         }
  37. }
复制代码
  1. package cn.itcast.day1;
  2. import java.lang.reflect.*;

  3. public class TestReflect
  4. {
  5.         public static void main(String[] args) throws Exception {
  6.                 //通过反射方式创建Student实例对象。constructor3代表具有三个参数的构造方法。
  7.                 Constructor constructor3= new Student().getClass().getConstructor(String.class,int.class,String.class);
  8.                 Student stu= (Student)constructor3.newInstance("zhangsan",26,"fudandaxue");
  9.                
  10.                 //访问私有属性,并对其数值进行修改。
  11.                 Field fieldName = stu.getClass().getDeclaredField("name");
  12.                 fieldName.setAccessible(true);
  13.                 fieldName.set(stu, "lisi");
  14.                 System.out.println(stu);
  15.                
  16.                 //访问私有方法speak()。
  17.                 Method speakMethod = stu.getClass().getDeclaredMethod("speak");
  18.                 speakMethod.setAccessible(true);
  19.                 speakMethod.invoke(stu);
  20.                
  21.                 //调用未知类startingClassName的main方法。我是用上面的cn.itcast.TestStudent类进行测试。
  22.                 String startingClassName = args[0];
  23.                 Method mainMethod = Class.forName(startingClassName).getMethod("main",String[].class);
  24.                 mainMethod.invoke(null,(Object)new String[]{"1"});
  25.         }
  26. }
复制代码
问题1:如果用反射方式调用某一个类的main方法时,众所周知是用Method mainMethod = Class.forName(startingClassName).getMethod("main",String[] args),然后用mainMethod.invoke(null,(Object)new String[]{"1"})进行调用,可不可以在不投放参数的情况下调用main方法,就像(null,(Object)new String[]{"1"})中所刻意放进去的new String[]{"1"},我只想获得main方法中的代码,至于放不放参数有些疑问?有人会发问main(String[] args)它的参数列表便是String[]类型的,我们在获得并使用的时候当然要按照它的格式来投放参数,我也知道这一点,有没有这种可能,反射也可以像我们刚开始接触java时候不放任何参数直接对main()方法进行调用?
问题2:反射机制有利有弊
利:引申出框架结构
弊:破坏了面向对象的封装性,可以对类中的私有属性、私有方法进行访问。过多反射会导致程序性能下降。
除了上面的利弊之外,具体还有哪些利弊?请详细说明!






评分

参与人数 1黑马币 +1 收起 理由
清风有意 + 1 赞一个!

查看全部评分

1 个回复

倒序浏览
不传参数调用主函数,是不可能的吧,就连jvm都给main传了一个数组,
如果硬要这样的,你可以讲主函数所在的类创建一个方法,并让方法调用main默认给他传进参数
然后再用反射把这个方法发射直接调用,就可以运行到main了。

第二个问题:
优点:运行期类型的判断,动态类加载,动态代理使用反射。
缺点:性能是一个问题,反射相当于一系列解释操作,通知jvm要做的事情,性能比直接的java代码要慢很多。

反射的使用:小项目就无所谓了,大的项目中,为了性能的考虑,能不用反射就不用反射。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马