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