首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

请写出如下代码的运行结果(22),该如何处理

2012-02-23 
请写出如下代码的运行结果(22)Java codeimport java.lang.reflect.Methodimport java.util.ArrayListimp

请写出如下代码的运行结果(22)

Java code
import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class T {  public static synchronized void main(String[] a) throws Exception {    T t = new T();    Method m = t.getClass().getMethod("hasNext");    System.out.print(m.invoke(t));    List<T> list = new ArrayList<T>();    list.add(t);    Iterator it = list.iterator();    m = it.getClass().getMethod("hasNext");    System.out.print(m.invoke(it));  }  public boolean hasNext() {    return true;  }}


[解决办法]
trueException in thread "main" java.lang.IllegalAccessException:
[解决办法]
trueException in thread "main" java.lang.IllegalAccessException: Class T can not access a member of class java.util.AbstractList$Itr with modifiers "public"
 System.out.print(m.invoke(it));//出错
[解决办法]
打印 iterator 的hasnext()的所调用的底层方法
[解决办法]
探讨
trueException in thread "main" java.lang.IllegalAccessException: Class T can not access a member of class java.util.AbstractList$Itr with modifiers "public"
System.out.print(m.invoke(it));//出错

[解决办法]
你是来问问题的还是来面试的?????
[解决办法]
T的getClass返回T,他的hasNext是一个public 方法,所以可以正常调用,输出true;

而 Iterator的 getClass 返回的是一个 java.util.AbstractList$Itr
我们可以输出看看
System.out.println(it.getClass()); 

那个Itr是一个inner Class, 其 hasNext 不是一个public方法,所以无法调用。

关键就是Iterator是一个接口而已。

-------------------
此回复不是很清晰,请看后面的几位的精彩讲解。谢谢。 否则会引起局部误导。
[解决办法]
很高深,,,,,,来学习............
[解决办法]
代码:
Java code
import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class T {    public static synchronized void main(String[] a) throws Exception {        T t = new T();        Method m = t.getClass().getMethod("hasNext");        System.out.print(m.invoke(t));        List<T> list = new ArrayList<T>();        list.add(t);        Iterator it = list.iterator();        m = it.getClass().getMethod("hasNext");        System.out.print(m.invoke(it));    }    public boolean hasNext() {        return true;    }}
[解决办法]
探讨
打印 iterator 的hasnext()的所调用的底层方法

[解决办法]
呵呵,很有意思的一个问题!

ArrayList继承自AbstractList,其iterator()方法返回内部类Itr的一个实例,而AbstractList的内部类Itr签名是private
关键问题在最后一行"System.out.print(m.invoke(it));"上

Method的invoke方法参数是一个对象,内部到底决定是谁去调用这个Method呢?这里显然最后JVM决定用T来调用这个"hasNext"的Method对象,T肯定没有访问它的权利,至于底层原理,我会整明白再来回答,呵呵,上班暂时没空
[解决办法]
Java code
import java.lang.reflect.Method;public class T {  public static void main(String[] args)throws Exception{      T t = new T();      Sam sam = t.getIt();      Method m = sam.getClass().getMethod("f");      System.out.println(sam.getClass());      m.invoke(sam);  }  private class It implements Sam{      public void f(){    System.out.println("F method");      }  }  public Sam getIt(){     return new It();  }}public interface Sam{    public void f();} 


[解决办法]
原因我找到了,是package的问题,请看如下代码:

下面是3个模仿的类,用于测试,请注意其package为 a

Java code
package a;public interface MyCollection {  public MyIterator myIterator();}
[解决办法]
mark
[解决办法]
会不会 先顶在说!
[解决办法]
Itr是一个inner Class
[解决办法]
探讨
T的getClass返回T,他的hasNext是一个public 方法,所以可以正常调用,输出true;

而 Iterator的 getClass 返回的是一个 java.util.AbstractList$Itr
我们可以输出看看
System.out.println(it.getClass());

那个Itr是一个inner Class, 其 hasNext 不是一个public方法,所以无法调用。

关键就是Iterator是一个接口而已。

[解决办法]
mark,学习
[解决办法]
学习一下……
[解决办法]
探讨
很高深,,,,,,来学习............

[解决办法]
trueException in thread "main" java.lang.IllegalAccessException: Class Test can not access a member of class java.util.AbstractList$Itr with modifiers "public"

[解决办法]
mark
[解决办法]
看了 半天 晕乎!!
[解决办法]
第一次的类是T,调用T的方法时,打印True;
第二次的类是AbstractList,这个类里没有hasNext这个方法,所以抛出异常,但把hasNext改成AbstractList里有的方法就OK了。
[解决办法]
看了 半天 晕乎!!
[解决办法]
真晕阿 看不太懂
[解决办法]
受教了
[解决办法]
学习。。。
[解决办法]
呵呵,老紫竹真敬业!佩服一下……

现在可以把注意力几种在Package之间访问权限的判别机制问题上了!有待进一步研究……
受教学习了!
[解决办法]
呵呵 头有点晕了
[解决办法]
感觉是私有内部类在反射时的访问权限问题,同包可以访问到,不同包则不能,与普通的私有域有区别。
public的内部类不会出现上述问题。
[解决办法]
我想结果大家运行一下代码就都很清楚了,那么出现该问题的原因是什么呢?

这里出现 IllegalAccessException 异常的原因就是java.util.AbstractList$Itr
这个内部类不是公共的,它来自另外一个包:访问位于其他包中的非公共类型的成员是不合法的,这当然包括外部类中的私有内部类,
无论是一般的访问还是通过反射的访问,上述的禁律都是有效的。

那么使用反射又如何调用呢?这是提供用两种方法:

1.取消反射时的安全机制检查

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class T {
public static synchronized void main(String[] a) throws Exception {
T t = new T();
Method m = t.getClass().getMethod("hasNext");
System.out.print(m.invoke(t));
List<T> list = new ArrayList<T>();
list.add(t);
Iterator it = list.iterator();
m = it.getClass().getMethod("hasNext");


m.setAccessible(true);//注意这句
System.out.print(m.invoke(it));
}

public boolean hasNext() {
return true;
}
}

2.用内部类实现的接口构造Method对象

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class T {
public static synchronized void main(String[] a) throws Exception {
T t = new T();
Method m = t.getClass().getMethod("hasNext");
System.out.print(m.invoke(t));
List<T> list = new ArrayList<T>();
list.add(t);
Iterator it = list.iterator();
m = Iterator.class.getMethod("hasNext");//注意这句
System.out.print(m.invoke(it));
}

public boolean hasNext() {
return true;
}
}
[解决办法]
第二种方法也可以充分说明,虽然内部类是私用的,但它的公共方法在其它包内调用是没有任何问题的.只是调用时不能用原始类型(不可见),必须向上转型后才可调用.
[解决办法]
附整理后的新的测试代码,配合我13楼的代码

Java code
package b;import java.lang.reflect.Method;import a.MyArrayList;import a.MyCollection;import a.MyIterator;/*** * @author 赵学庆 <A href="http://www.java2000.net/" target=_blank>www.java2000.net</A>* @thanks Ant_Yan xunyiren**/public class TestInvoke {  public static void main(String[] args) throws Exception {    test1();    test2();    test3();  }  public static void test1() {    MyCollection t = new MyArrayList();    MyIterator sam = t.myIterator();    Method m;    try {      m = sam.getClass().getMethod("myHasNext");      m.invoke(sam);    } catch (Exception e) {      // TODO Auto-generated catch block      e.printStackTrace();    }  }  public static void test2() {    MyCollection t = new MyArrayList();    MyIterator sam = t.myIterator();    Method m;    try {      m = sam.getClass().getMethod("myHasNext");      m.setAccessible(true); // 此处设置了取消安全检测      m.invoke(sam);    } catch (Exception e) {      // TODO Auto-generated catch block      e.printStackTrace();    }  }  public static void test3() {    MyCollection t = new MyArrayList();    MyIterator sam = t.myIterator();    Method m;    try {      m = MyIterator.class.getMethod("myHasNext"); // 此处使用了接口自身      m.invoke(sam);    } catch (Exception e) {      // TODO Auto-generated catch block      e.printStackTrace();    }  }} 

热点排行