Class对象与反射

Class 对象

Java中所有类型(包括基本类型)都对应一个Class对象,这个Class就是java.lang.Class。即每一个类型,都有一个Class对象跟它对应.Class 没有公共构造方法。注意不是没有,是没有公共的.

换言之,每次写一个新类时,同时也会创建一个Class 对象(更恰当地说,是保存在一个完全同名的.class 文件中)。在运行期,一旦我们想生成那个类的一个对象,用于执行程序的 Java 虚拟机(JVM)首先就会检查那个类型的 Class 对象是否已经载入。若尚未载入,JVM 就会查找同名的.class 文件,并将其载入。所以 Java 程序启动时并不是完全载入的,这一点与许多传统语言都不同。一旦那个类型的 Class 对象进入内存,就用它创建那一类型的所有对象。

获取Class对象的方法

有2种方法,forName和class

Class.forName("Gum");

该方法是 Class(即全部 Class 所从属的)的一个 static 成员。而 Class 对象和其他任何对象都是类似的,所以能够获取和控制它的一个句柄(装载模块就是干这件事的)。此方法会载入类。

在 Java 1.1 中,可以采用第二种方式来产生 Class 对象的句柄:使用“类标记”。对上述程序来说,看起来
就象下面这样:
Gum.class;
这样做不仅更加简单,而且更安全,因为它会在编译期间得到检查。由于它取消了对方法调用的需要,所以
执行的效率也会更高。而且不像forname会抛异常

instance of

if(x instanceof Dog)

在 Java 1.0 中,对 instanceof 有一个比较小的限制:只可将其与一个已命名的类型比较,不能同 Class 对
象作对比,后来java 1.1加入isinstance可以同Class对象作对比

Class方法

Class.getInterfaces 方法会返回 Class 对象的一个数组,用于表示包含在 Class 对象内的接口。

 getSuperclass()查询该对象的直接基础类是什么

 newInstance() 方法 用 newInstance() 创建的类必须有一个默认构建器。
没有办法用 newInstance() 创建拥有非默认构建器的对象

Class 方法 getMethods()getConstructors()可以分别返回 Method 和 Constructor 的一个数组



反射

declared的方法是支持私有,但是不支持继承,declared的方法支持继承,不支持私有,且只能取出public的东西.

declaered可以获取到各种权限的属性,方法,无declared只能获取public的

但是declared获取不到从父类继承来的方法和属性,无declare的就可以

int getModifiers() 
                      返回此Method或Field或Constructor所表示的方法或域或构造方法的 Java 语言修饰符的整数形式。 
                      如果同时被多个修饰符修饰那么返回的是各个修饰符常量的和, 修饰符的编码解码由Modifier 类描述

Constructor conAll = c.getConstructor(int.class,String.class,int.class);
    Object caobj = conAll.newInstance(1001,"zjamgs",234235);//调用含参的构造方法.


如何反射获取private类或者package类

不能用newInstance来直接构造,但是可以去获取构造函数,用构造函数来构造



[for not nested classes]

I assume that constructors of that class are not public. In that case you can do it this way

Lets say you have class A in some package

package package1;

public class A {
    A(){
        System.out.println("this is default constructor");
    }
}

to create its object you can use its constructor like this

Class<?> c = Class.forName("package1.A");//full package name
//note: getConstructor() can return only public constructors,
//you need to use 
Constructor<?> constructor = c.getDeclaredConstructor();

constructor.setAccessible(true);
Object o = constructor.newInstance(null);

[for nested classes]

If you want to get Class of inner class with Class.forName you need to use this form

Class<?> clazz = Class.forName("package1.Outer$Inner");

$ says that class after it is inner. Inner classes are very similar to methods, they have access to all members of its outer class, and to exists/work need instance of that outer class, so while creating instance of Inner class you have to pass reference to instance of Outer class.

Here is example.

package1

package package1;

public class Outer {
    class Inner{
        Inner(){
            System.out.println("default constructor of inner class");
        }
    }
}

package2

package package2;

import package1.Outer;
import java.lang.reflect.Constructor;

public class Test {
    public static void main(String[] args) throws Exception {

        Outer outerObject = new Outer();

        Class<?> innerClazz = Class.forName("package1.Outer$Inner");

        // constructor of inner class as first argument need object of
        // Outer class
        Constructor<?> constructor = innerClazz.getDeclaredConstructor(Outer.class);

        //we need to make constructor accessible 
        constructor.setAccessible(true);

        //now we need to pass instance of outer class in constructor
        Object o = constructor.newInstance(outerObject);

        System.out.println("we created object of class: "+o.getClass().getName());

    }
}

如何修改final参数

public class EverythingIsTrue {
   static void setFinalStatic(Field field, Object newValue) throws Exception {
//      field.setAccessible(true);

      Field modifiersField = Field.class.getDeclaredField("modifiers");
      modifiersField.setAccessible(true);
      modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

      field.set(null, newValue);
   }
   public static void main(String args[]) throws Exception {      
      setFinalStatic(Boolean.class.getField("FALSE"), true);

      System.out.format("Everything is %s", false); // "Everything is true"
   }
}

<pre name="code" class="java">Field 类里有个变量<pre name="code" class="java">modifiers,是私有的,代表着这个Field的修饰符信息,比如static ,final,violate,这些都会被转化为一个MASK值,要去掉final只要改变这个modifiers就可以了
 
 

参考文献

 java编程思想

http://www.cnblogs.com/dennisit/archive/2013/02/26/2933508.html

http://www.bubuko.com/infodetail-379319.html

http://stackoverflow.com/questions/15015675/accessing-non-visible-classes-with-reflection

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值