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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 唐辉辉 中级黑马   /  2012-6-28 11:10  /  3799 人查看  /  17 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 唐辉辉 于 2012-6-29 13:06 编辑
  1. import java.util.ArrayList;


  2. public class FanXingDemo2 {
  3.         
  4.         public static void main(String[] args) throws Exception{
  5.                
  6.                 ArrayList<String> arrList = new ArrayList<String>();
  7.                
  8.                 arrList.add("123");
  9.                
  10.                 arrList.getClass().getMethod("add", Object.class).invoke(arrList, 123);
  11.                
  12.                 System.out.println(arrList.get(1));
  13.         }
  14. }
复制代码
  1. import java.util.ArrayList;


  2. public class FanXingDemo2 {
  3.         
  4.         public static void main(String[] args) throws Exception{
  5.                
  6.                 ArrayList<Integer> arrList = new ArrayList<Integer>();
  7.                
  8.                 arrList.add(123);
  9.                
  10.                 arrList.getClass().getMethod("add", Object.class).invoke(arrList, "123");
  11.                
  12.                 System.out.println(arrList.get(1));
  13.         }
  14. }
复制代码
为什么第一段代码取出时会报异常,而第二段代码不会:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
        at FanXingDemo2.main(FanXingDemo2.java:14)

在第一段代码中,已经知道arrList有两个值,一个为String类型,一个为Integer。通过arrList.get()方法 返回,是返回的一个泛型类型的值,也就是我指定的String。 所以会报类型转换异常,但是为什么第二段代码他不报错呢?  明明我指定的是Integer的泛型。利用反射存入的是String类型的值。这时arrList.get()方法返回应该是Integer,为什么这里返回的是String。没有报错。而第一段代码报错了。


17 个回复

倒序浏览
不是都看到这个异常了么
java.lang.Integer cannot be cast to java.lang.String
我感觉你是为了给大家加分了,我就不仔细说了。
回复 使用道具 举报
本帖最后由 唐辉辉 于 2012-6-28 11:35 编辑
闾丘日月 发表于 2012-6-28 11:15
不是都看到这个异常了么
java.lang.Integer cannot be cast to java.lang.String
我感觉你是为了给大家加分 ...

:L    不对, 我真没搞得懂,  麻烦你跟我说下。    Integer 转 String 不能转, 那为什么String 转 Integer能转呢?
回复 使用道具 举报
这样才是对的..
  1. public class Test7 {
  2.                 public static void main(String[] args) throws Exception{
  3.                         
  4.                         ArrayList<String> arrList = new ArrayList<String>();
  5.                         
  6.                         arrList.add("123");
  7.                         
  8.                         arrList.getClass().getMethod("add", Object.class).invoke(arrList, "123");
  9.                         
  10.                         System.out.println(arrList.get(1));
  11.                 }
  12.         }
复制代码
add(int index, E element)   将指定的元素插入此列表中的指定位置...
第二个参数必须是字符型... 你传进的是个整型肯定会报错...
回复 使用道具 举报
本帖最后由 唐辉辉 于 2012-6-28 13:15 编辑
常佳杰 发表于 2012-6-28 12:16
这样才是对的..add(int index, E element)   将指定的元素插入此列表中的指定位置...
第二个参数必须是字符 ...

add(int index, E element)
第二个参数并没有指定是某种类型,   这里明明是一个泛型。虽然我在前面指定了这个泛型为String ,但是在 这个类的字节码中已经去除了这个泛型的类型。所以,我放任何类型的元素都应该是可以的。 并且报错的是 14 行。
回复 使用道具 举报
哦 写错了 应该是
invoke(arrList, "123");
这个的第二个...
这样就有结果了
回复 使用道具 举报
常佳杰 发表于 2012-6-28 13:22
哦 写错了 应该是
invoke(arrList, "123");
这个的第二个...

我知道这样是正确的,   麻烦你讲下原因。是哪里出的问题,为什么?
回复 使用道具 举报
同上面说的
java.lang.Integer cannot be cast to java.lang.String
下面这样写就可以呵呵
import java.util.ArrayList;
class FanXingDemo2 {
        public static void main(String[] args) throws Exception {
                ArrayList<? super String> arrList = new ArrayList();
                arrList.add("123");
                arrList.getClass().getMethod("add", Object.class).invoke(arrList, 123);
                System.out.println(arrList.get(1));
        }
}
回复 使用道具 举报
李天甲 发表于 2012-6-28 13:48
同上面说的
java.lang.Integer cannot be cast to java.lang.String
下面这样写就可以呵呵

说说为什么啊?  我写的为什么错了?

还有, 为什么你指定<?  super  String>可以呢?
回复 使用道具 举报
楼上说的不错,但是编译是会有注意,而且不能解决LZ的第二种代码

方法里面这样写就能解决楼主的问题了!

ArrayList<Object> arrList = new ArrayList<Object>();
                                
                arrList.add("123");
                                
                arrList.getClass().getMethod("add", Object.class).invoke(arrList, 12);
               
                for(Object obj : arrList)
                {
                        System.out.println(obj);
                }
回复 使用道具 举报
public class Test7 {
                public static void main(String[] args) throws Exception{
                        
                        ArrayList<String> arrList = new ArrayList<String>();
                        
                        arrList.add("123");
                        
                        arrList.getClass().getMethod("add", Object.class).invoke(arrList, 123);
                        
                        System.out.println(arrList.get(0));
                }
        }
这样不会出问题,输出:
123
我的理解是这样的..
arrList.getClass().getMethod("add", Object.class).invoke(arrList, 123);这句话虽然把123添加进去了..
存进去的123共占12个字节,存到数组中它是字符型...
但是当你用arrList.get(1)..得这个数组中的索引值为1的时候..编译器从中取1个字节时出错,
取不出来..
但是迭代一下就能输出0,1索引处的值

public class FanXingDemo2 {
                        ArrayList<String> arrList1 = new ArrayList<String>();
                        
                        arrList1.add("123");
                        
                        arrList1.getClass().getMethod("add", Object.class).invoke(arrList,123);
                       
                        System.out.println(arrList1.get(0));
                        
                        Iterator it = arrList1.iterator();
                        while(it.hasNext()){
                                System.out.println(it.next());
                        }

输出:
123
123

点评

关键点在print方法的重载参数匹配上,如果找不到范型参数类型的重载方法,就会强制转换,所以会报错  发表于 2012-6-28 17:38

评分

参与人数 1技术分 +1 收起 理由
刘蕴学 + 1

查看全部评分

回复 使用道具 举报
楼主看看,这个弄了好长时间,可能就是这个原因..
回复 使用道具 举报
呵呵,的确是System.out.println(arrList.get(1));
这一句搞得鬼
调试了一下,完全可以存进去,但是输出的时候因为有了泛型的限定,所以根本输出不出来,记得哪里回答过...
10楼正解.....
回复 使用道具 举报
常佳杰 发表于 2012-6-28 14:29
public class Test7 {
                public static void main(String[] args) throws Exception{
       ...

感谢你的回答:

你写的这个已经避开了问题。it.next()输出的是一个对象,所以任意类型的对象都可以输出,是没错的。 我的问题是在第一段代码中,已经知道arrList有两个值,一个为String类型,一个为Integer。通过arrList.get()方法 返回,是返回的一个泛型类型的值,也就是我指定的String。 所以会报类型转换异常,但是为什么第二段代码他不报错呢? 明明我指定的是Integer的泛型。利用反射存入的是String类型的值。这时arrList.get()方法返回应该是Integer,为什么这里返回的是String。没有报错。而第一段代码报错了。
回复 使用道具 举报
李天甲 发表于 2012-6-28 14:34
呵呵,的确是System.out.println(arrList.get(1));
这一句搞得鬼
调试了一下,完全可以存进去,但是输出的时候 ...

第二段代码也有泛型限定。 为什么没有报错,正确的输出了呢?
回复 使用道具 举报
胡文杰 发表于 2012-6-28 14:16
楼上说的不错,但是编译是会有注意,而且不能解决LZ的第二种代码

方法里面这样写就能解决楼主的问题了!

感谢!

问题是:

在第一段代码中,已经知道arrList有两个值,一个为String类型,一个为Integer。通过arrList.get()方法 返回,是返回的一个泛型类型的值,也就是我指定的String。 所以会报类型转换异常,但是为什么第二段代码他不报错呢?  明明我指定的是Integer的泛型。利用反射存入的是String类型的值。这时arrList.get()方法返回应该是Integer,为什么这里返回的是String。没有报错。而第一段代码报错了。

点评

函数匹配导致的  发表于 2012-6-28 17:36
回复 使用道具 举报
第一个出错的原因是,arrlist运行的时候去类型化,存到i里面的都是Object类型的,你可以debug看一下,当你去取的时候你本身定义为Integer却取到一个String ,有没有调用什么方法进行转换 所以会出错
第二个不会出错就是下面,他会先给你转换一下,再输出

println
public void println(Object x)
Prints an Object and then terminate the line. This method calls at first String.valueOf(x) to get the printed object's string value, then behaves as though it invokes print(String) and then println().
回复 使用道具 举报
第一个出错的原因是,arrlist运行的时候去类型化,存到i里面的都是Object类型的,你可以debug看一下,当你去取的时候你本身定义为Integer却取到一个String ,有没有调用什么方法进行转换 所以会出错
第二个不会出错就是下面,他会先给你转换一下,再输出

println
public void println(Object x)
Prints an Object and then terminate the line. This method calls at first String.valueOf(x) to get the printed object's string value, then behaves as though it invokes print(String) and then println().
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马