黑马程序员技术交流社区

标题: 关于反射获取class对象的问题 [打印本页]

作者: 温晓慧    时间: 2015-1-17 21:24
标题: 关于反射获取class对象的问题
反射的用法:

1)、需要获得java类的各个组成部分,首先需要获得类的Class对象,获得Class对象的三种方式:

1.Class.forName(classname)用于做类加载
这个方法是class类的一个static成员,一调用这个类自动在虚拟机中初始化!

2.obj.getClass()用于获得对象的类型

3.类名.class    用于获得指定的类型,传参用
这个使用不仅更简单而且更安全,因为它在编译的时候就受到检查,因此不需要置于try语句中!这个创建class对象的时候不会自动初始化该对象!



作者: 温晓慧    时间: 2015-1-17 21:28
  1. package com.itheima;


  2. import java.util.Random;


  3. public class Reflection {
  4.         public static Random rand =new Random(47);

  5.         public static void main(String[] args)throws Exception {
  6.                 Class<Demo1> Demo1 = Demo1.class;
  7.                 System.out.println("Demo1.class建立了");
  8.                
  9.                 System.out.println(Demo1.staticFinal);
  10.                 System.out.println(Demo1.staticFinal2);
  11.                 System.out.println(Demo2.staticNonFinal);
  12.                 Class<?> Demo3 = Class.forName("Demo3");
  13.                 System.out.println("Demo3.class建立了");
  14.                 System.out.println(Demo3.staticNonFinal);
  15.                
  16.        
  17.         }

  18. }
  19. class Demo1
  20. {
  21.         public static final int staticFinal=47;
  22.         public static final int staticFinal2=
  23.                         Reflection.rand.nextInt(1000);
  24.         static
  25.         {
  26.                 System.out.println("Demo1初始化了");
  27.         }
  28. }
  29. class Demo2
  30. {
  31.         static int staticNonFinal=157;
  32.         static
  33.         {
  34.                 System.out.println("Demo2初始化了");
  35.         }
  36. }
  37. class Demo3
  38. {
  39.         static int staticNonFinal=99;
  40.         static
  41.         {
  42.                 System.out.println("Demo3初始化了");
  43.                
  44.         }
  45. }
复制代码

想用这个证实一下,结果变异就不通过
main函数中syso( Demo1.staticFinal )不通过
syso( Demo1.staticFinal2 )不通过
syso( Demo3.staticNonFinal )不通过
为啥呢?


作者: bowen-xiao    时间: 2015-1-17 21:41
static成员程序运行时就已经加载到内存,它一直存在于内存中就是为了方便调用,所以可以直接访问。
作者: 温晓慧    时间: 2015-1-18 00:14
bowen-xiao 发表于 2015-1-17 21:41
static成员程序运行时就已经加载到内存,它一直存在于内存中就是为了方便调用,所以可以直接访问。 ...

对,static final属于常量,可以不用初始化就调用,但是为啥编译报错呢?不懂了。。。大神求指教
作者: bowen-xiao    时间: 2015-1-18 10:48
本帖最后由 bowen-xiao 于 2015-1-18 11:17 编辑
温晓慧 发表于 2015-1-18 00:14
对,static final属于常量,可以不用初始化就调用,但是为啥编译报错呢?不懂了。。。大神求指教 ...

static final属于常量这个没有问题,下面调用用所有的成员变量的方法。
  1.       public static void main(String[] args)throws Exception {
  2. //                Class<Demo1> Demo1 =  com.itheima.Demo1.class;
  3.                 Demo1 Demo1 = (Demo1)Class.forName("com.itheima.Demo1").newInstance();
  4.                 Field[] fields = Demo1.getClass().getFields();
  5.                 for (Field field : fields) {
  6.                                  
  7.                         
  8. //                        获取成员变量的类型是否为public staic fianl
  9. //                        参考http://www.2cto.com/kf/201211/165674.html
  10.                         if(field.getModifiers() == 25){
  11.                                 
  12.                                  System.out.print("名称:" + field.getName() +"="+ field.get(Demo1) +"\t");   
  13.                         }
  14.                                 }
  15.         }
复制代码


方法二:直接指定成员变量名,直接调取
  1.    public static void main(String[] args)throws Exception {

  2. //根据变量名称直接获取到指定的成员变量
  3.                 Class<Demo1> Demo2 =  com.itheima.Demo1.class;
  4.                 Field field2 = Demo2.getDeclaredField("staticFinal");
  5.                 System.out.println(field2.get(Demo2));

  6.         }
复制代码




作者: 不给吃鸭梨    时间: 2015-1-18 11:11
楼上说的类加载器应该是字节码文件,静态字段加载的时候就如楼上所说是得要实例的,但是静态代码块是在类load进内存的时候就所做的初始化可以通过。

有一个命令-verboss:Class  记得是这个可以看到类在加载的时候具体详细信息。
作者: 周景新    时间: 2015-1-18 12:29
学习了。。。
作者: 温晓慧    时间: 2015-1-18 13:00
不给吃鸭梨 发表于 2015-1-18 11:11
楼上说的类加载器应该是字节码文件,静态字段加载的时候就如楼上所说是得要实例的,但是静态代码块是在类lo ...

这个也是学习了
作者: 温晓慧    时间: 2015-1-18 13:42
bowen-xiao 发表于 2015-1-18 10:48
static final属于常量这个没有问题,下面调用用所有的成员变量的方法。

哦哦。。。这样子,,谢谢大神
作者: shenshuangxi    时间: 2015-1-18 22:39
很明显啊,你获得的是类的字节码,它已经不是类名,然后用类的字节码去调用它里面的变量,当然不可以,你需要继续用反射来获取成员变量,然后得到它的值
Field field= Demo1.getDeclaredField("staticFinal");
               System.out.println(field);
               System.out.println(field.get(null));
作者: 志ぁ才☆博ぁ成    时间: 2015-1-18 23:14
看来你学的的挺快啊




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2