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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 褚代江 中级黑马   /  2012-5-15 10:52  /  3224 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

昨晚上看了后本以为很快做出来,结果搞到断网后,才弄出来,一个地方我就不懂了,红字的什么情况
  1. import java.lang.reflect.Method;
  2. public class Fanshe {
  3.         public static void main(String[] args) throws Exception{
  4.                 //得到构造函数,创建该类的对象
  5.                 Person p=Person.class.getConstructor().newInstance();
  6.                
  7.                 Method me=Person.class.getMethod("work");
  8.                 me.invoke(p);
  9.         }
  10. }
  11. class Person{
  12.         public Person(){}//[color=Red]必须重写,这个地方不写的话,总是运行是报错的,说没有这个构造方法,我就郁闷了,每个类都有一个默认的构造函数啊,怎么用反射的就得不到默认的构造函数了,必须自己写一个空参数的构造函数(这前面的修饰还必须是public,用默认和protected都不行,这都是什么情况啊?这两个类都在同一个包里面,怎么就访问不到了呢)[/color]        public void work()
  13.         {
  14.                 System.out.println("人在工作");
  15.         }
  16. }
复制代码
看来反射还没学到家啊,求解决啊

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

7 个回复

正序浏览
李哲 发表于 2012-5-16 09:04
请注意你第一个观点的错误。
运行以上代码即知。

嗯,已修正:)
回复 使用道具 举报
李哲 中级黑马 2012-5-16 09:04:04
7#
云惟桉 发表于 2012-5-16 00:41
我想分两点来分析一下楼主遇到的问题:
第一、楼主的注释:必须重写,这个地方不写的话,总是运行是报错的 ...
  1. public class Fanshe {
  2.         public static void main(String[] args) throws Exception{                  
  3.                 Person1 p=Person1.class.getDeclaredConstructor().newInstance();                  
  4.                 Method me=Person1.class.getMethod("work");
  5.                 me.invoke(p);               
  6.                  
  7.         }
  8. }
  9. class Person1{            
  10.         public void work()
  11.         {
  12.                 System.out.println("人在工作");
  13.         }
  14. }
复制代码
请注意你第一个观点的错误。
运行以上代码即知。

回复 使用道具 举报
上面哥们说的很清楚了,还有就是如果是缺省的构造函数它的修饰符是和你定义的类的修饰符一致的,如果你没有写public修饰类,那么你的缺省构造函数就是默认的权限(包可见)。所以你要加上public才行,如果你想编译成功,还有一个方法,就是将这短代码写在两个java源文件里,都用public修饰类,person类你就不用显示地写出缺省的构造函数了。
回复 使用道具 举报
本帖最后由 云惟桉 于 2012-5-16 12:48 编辑

我想分两点来分析一下楼主遇到的问题:

第一、【Class类里的newInstance】:
楼主的注释:必须重写,这个地方不写的话,总是运行是报错的,说没有这个构造方法,我就郁闷了,每个类都有一个默认的构造函数啊,怎么用反射的就得不到默认的构造函数了,必须自己写一个空参数的构造函数。
楼主理解的意思是每个类都有一个缺省构造函数,但不是这样的。如果该类显式的声明了任意一个构造函数(无参或有参),就不会再给该类分配一个缺省构造函数了。
[题外话]:
要使用Class类里的newInstance()来生成对象,你的类就必须要有一个无参构造函数。
如果该类没有显示定义任何构造函数,那么会给该类提供一个缺省的构造函数。缺省的构造函数就是无参的。
如果该类有定义构造函数,那么就必须包含一个无参的构造函数,否则就会创建对象失败。

第二、【Constructor类里的newInstance】:
楼主注释:这前面的修饰还必须是public,用默认和protected都不行,这都是什么情况啊?这两个类都在同一个包里面,怎么就访问不到了呢
查看getConstructor的API就知道了:
返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。就是public权限的才行。
是公共构造方法,因此,楼主应该明白为什么出错了吧。
如果不用public权限修饰,那么找不到对应的公共构造方法,就无法使用对应的构造函数newInstance生成实例对象(注意:这里使用newInstance的是Constructor对象,不是Class对象)。
如楼上说明的,楼主可以使用getDeclaredConstructor

希望能帮到你。另外感谢7楼指出的错误,当时对缺省和无参理解有误区,并且还有一部分理解和C++里的概念有混淆。
已经改正过了,并且尽力使回答更具针对性。希望大家都能交流指教。
回复 使用道具 举报
getConstructor
public Constructor<T> getConstructor(Class<?>... parameterTypes)
                              throws NoSuchMethodException,
                                     SecurityException返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法
getDeclaredConstructor
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
                                      throws NoSuchMethodException,
                                             SecurityException返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法
正如如你所说,其实不加public,默认,Fanshe类中是可以创建Person实例的。
之所以出错,原因在于getConstructor是要得到public的构造函数。所以二楼使用的getDeclaredConstructor就可以不用加public。
回复 使用道具 举报
zlghff 发表于 2012-5-15 12:07
需要getDeclaredConstructor(),这是对非public的获取,pravite时要暴力反射。小知识点一个
例如:
Person{ ...

我2了啊。

这个你去问下刘老师,群里就有,小窗口问下就可以了
回复 使用道具 举报
需要getDeclaredConstructor(),这是对非public的获取,pravite时要暴力反射。小知识点一个
例如:
Person{

void run()
{
System.out.println("hahah");
}

}
-----------------------------------------
import java.lang.reflect.*;

class Demo2{
public static void main(String [] args)throws Exception{
Constructor  con=Person.class.getDeclaredConstructor();
Person  p=(Person)con.newInstance() ;
p.run();

}

}

兄弟问一下,名字没改成真名可以给分吗,可以申请入学考试吗?

我一直等管理员给我改名,祝你好运。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马