Java_反射_Class类(Method,Field,Constructor)
2013-05-15 18:08
405 查看
本博文为子墨原创,转载请注明出处!
http://blog.csdn.net/zimo2013/article/details/8931639
(1).Class clazz = Person.class;
(2).Class clazz = P.getClass();
(3).Class clazz = Class.forName("String
path");
(4).Class clazz = ClassLoader.getSystemClassLoader().loadClass("com.baidu.Person");
上述四种字节码可以获得字节码对象,在获得之前先判断是否载入,没有则查找载入(还可以通过类的实例化对象载入),否则返回先前载入的class,符合单例设计模式!
通过类加载器将需求类加载至内存中,类加载器会采用事件委托机制,如果该类已经加载,则不需重新再加载!实现步骤:
1).调用 findLoadedClass(String) 来检查是否已经加载类。
2).在父类加载器上调用 loadClass 方法。如果父类加载器为 null,则使用虚拟机的内置类加载器。
3).调用 findClass(String) 方法查找类。
更多类加载器参考>>
注意:与通过代理获得的字节码区别
和
getConstructor(Class<?>...
parameterTypes)
返回一个
Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
getDeclaredConstructor(Class<?>...
parameterTypes)
所有非public的构造方法,都应该用该方法获取,而public可以使用getConstructor
getConstructors()
返回Constructor
对象数组
getDeclaredConstructors()
Constructor的操作过程
Constructor<Person>
con = Person.class.getDeclaredConstructor(String.class, int.class);//与构造函数一致
Person
p = con.newInstance("haha", 10);//newInstance实现
2).获取Field对象
getField(String
name)
返回一个包含某些
Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。
getDeclaredField(String
name)
getFields()
getDeclaredFields()
Field的操作过程
Field
f = Person.class.getDeclaredField("name");//能看见
f.setAccessible(true); //指示反射的对象在使用时是否取消
Java 语言访问检查能用
f.set(p,
"zhangsan"); //指定该字段所对应的对应的值
Field的常见方法
Object
get(Object obj)
String
s1 = (String)ff.get(p);//返回Object类要进行强转
getType()
返回一个class类型的二进制码文件
set(Object
obj, Object value)
f.setAccessible(true)
3).获取Method对象
getMethod(String
name, Class<?>... parameterTypes) //由于方法名队员可能有多个函数,应该在其后指明对应的class对象
返回一个
Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
getDeclaredMethod(String
name, Class<?>... parameterTypes)
getMethods()
getDeclaredMethods()
Method的操作过程
Method
m = Person.class.getMethod("set", String.class, int.class);
m.invoke(p,
"wangwu", 100);
4).Class也能newInstance()!!!
Person
p = (Person)Class.forName("Person").newInstance();
T
newInstance(),但是只能为空参数!!!注意和Constructor的newInstance的区别~~~得到的是一个对象Object要注意转换
5).Perosn.class.getResourceAsStream(String path)
path 不以 / 开头时默认是从此类所在的包下取资源(即Person所在的类class目录中,存在一个path文件)
path 以 / 开头,以ClassPath根下获取一个绝对路径。
6).Perosn.class.getClassLoader().getResourceAsStream(String path)
默认则是从ClassPath根下获取
凡是为静态的字段或者方法,其对应的对象为null!
http://blog.csdn.net/zimo2013/article/details/8931639
1.获得字节码实例对象
Person p = new Person();(1).Class clazz = Person.class;
(2).Class clazz = P.getClass();
(3).Class clazz = Class.forName("String
path");
(4).Class clazz = ClassLoader.getSystemClassLoader().loadClass("com.baidu.Person");
上述四种字节码可以获得字节码对象,在获得之前先判断是否载入,没有则查找载入(还可以通过类的实例化对象载入),否则返回先前载入的class,符合单例设计模式!
通过类加载器将需求类加载至内存中,类加载器会采用事件委托机制,如果该类已经加载,则不需重新再加载!实现步骤:
1).调用 findLoadedClass(String) 来检查是否已经加载类。
2).在父类加载器上调用 loadClass 方法。如果父类加载器为 null,则使用虚拟机的内置类加载器。
3).调用 findClass(String) 方法查找类。
更多类加载器参考>>
System.out.println(P.getClass().getClass().getClass().getName());//字节码的字节码A是Class,A字节码的字节码还是Class
注意:与通过代理获得的字节码区别
public static void main(String[] args) throws Exception { Class clazz1 = List.class; Class clazz2 = Class.forName("java.util.List"); Class clazz3 = ClassLoader.getSystemClassLoader().loadClass("java.util.List"); Class clazz4 = Proxy.getProxyClass(null, List.class); System.out.println(clazz1 == clazz2); //true System.out.println(clazz1 == clazz3); //true System.out.println(clazz1 == clazz4); //false /* * getProxyClass(null, Class<?> ...)接收的是可变参数而普通的是的单个类或者接口 * 显然Class字节码文件不一样 */ }
2.九中预定义[b]字节码实例对象[/b]
有九种预定义的Class对象,表示八个基本类型和 void,象由 Java 虚拟机创建,与其表示的基本类型同名,即
boolean、
byte、
char、
short、
int、
long、
float
和
double
System.out.println(int.class == Integer.TYPE); //true 其中Integer.TYPE中TYPE字段表示基本类型 int的 Class 对象。 System.out.println(int.class.isPrimitive()); //true 判定指定的 Class 对象是否表示一个基本类型
3.Class主要方法
1).获取Constructor对象getConstructor(Class<?>...
parameterTypes)
返回一个
Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
getDeclaredConstructor(Class<?>...
parameterTypes)
所有非public的构造方法,都应该用该方法获取,而public可以使用getConstructor
getConstructors()
返回Constructor
对象数组
getDeclaredConstructors()
Constructor的操作过程
Constructor<Person>
con = Person.class.getDeclaredConstructor(String.class, int.class);//与构造函数一致
Person
p = con.newInstance("haha", 10);//newInstance实现
2).获取Field对象
getField(String
name)
返回一个包含某些
Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。
getDeclaredField(String
name)
getFields()
getDeclaredFields()
Field的操作过程
Field
f = Person.class.getDeclaredField("name");//能看见
f.setAccessible(true); //指示反射的对象在使用时是否取消
Java 语言访问检查能用
f.set(p,
"zhangsan"); //指定该字段所对应的对应的值
Field的常见方法
Object
get(Object obj)
String
s1 = (String)ff.get(p);//返回Object类要进行强转
getType()
返回一个class类型的二进制码文件
set(Object
obj, Object value)
f.setAccessible(true)
3).获取Method对象
getMethod(String
name, Class<?>... parameterTypes) //由于方法名队员可能有多个函数,应该在其后指明对应的class对象
返回一个
Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
getDeclaredMethod(String
name, Class<?>... parameterTypes)
getMethods()
getDeclaredMethods()
Method的操作过程
Method
m = Person.class.getMethod("set", String.class, int.class);
m.invoke(p,
"wangwu", 100);
4).Class也能newInstance()!!!
Person
p = (Person)Class.forName("Person").newInstance();
T
newInstance(),但是只能为空参数!!!注意和Constructor的newInstance的区别~~~得到的是一个对象Object要注意转换
5).Perosn.class.getResourceAsStream(String path)
path 不以 / 开头时默认是从此类所在的包下取资源(即Person所在的类class目录中,存在一个path文件)
path 以 / 开头,以ClassPath根下获取一个绝对路径。
6).Perosn.class.getClassLoader().getResourceAsStream(String path)
默认则是从ClassPath根下获取
4.总结
总之,对于一个已经存在的实例对象A,假想操作字段或者方法,必得到一个Field或者Method的对象X,对于一个X必须有指定一个的A对象,才能完成对A对象属性的修改。对于不存在的A,可以通过构造函数,返回A凡是为静态的字段或者方法,其对应的对象为null!
5.反射代码实例
/* 反射的简单应用 Strawberry2013/5/15 */ import java.lang.reflect.*; class Demo { public static void main(String[] args) throws Exception { //Constructor Constructor<Person> con = Person.class.getDeclaredConstructor(String.class, int.class); //需注意加泛型 由于Person类的构造函数是非public的,故应该使用getDeclaredConstructor()方法 Person p = con.newInstance("haha", 10);//实例化对象 p.show(); //Field Field f = Person.class.getDeclaredField("name");//获得单个字段,必须指明字段对应的字符串 //Field f = Perosn.class.getField("name");该方法只能获取字段为public的 f.setAccessible(true); //指示反射的对象在使用时是否取消 Java 语言访问检查 f.set(p, "zhangsan"); //指定该字段所对应的对应的值 p.show(); Field[] fs = Person.class.getDeclaredFields();//获得全部的字段,数组 for(Field ff: fs) { if(!ff.isAccessible()) ff.setAccessible(true); if(ff.getType() == String.class)//getType()返回的是一个class的二进制码文件,由于该文件具有唯一性,直接用等于号进行判断 { ff.set(p, "lisi"); // 得到该字段的对应值,进行修改! //String s1 = (String)ff.get(p);//get()方法返回的是Object类型,必须进行强制向下转换 //String s = ...修改语句; //ff.set(p, s); } } p.show(); //Method Method m = Person.class.getMethod("set", String.class, int.class); m.invoke(p, "wangwu", 100); p.show(); Method mm = Person.class.getMethod("haha"); //静态方法的处理 mm.invoke(null);//此处为null,凡是为静态的字段或者方法,实例对象位置为null Field f1 = Person.class.getDeclaredField("country");//静字段的处理 f1.setAccessible(true); String ss = (String)f1.get(null); System.out.println(ss); f1.set(null, "usa"); Person.haha(); } } class Person { private int age; private String name; private static String country = "zn"; Person(){} Person(String name, int age) { this.name = name; this.age = age; } public void show() { System.out.println(name+":"+age); } public void set(String name, int age) { this.name = name; this.age = age; } public static void haha() { System.out.println("country:"+country); } }
相关文章推荐
- Java_反射_Class类(Method,Field,Constructor)
- JAVA进阶之旅(二)——认识Class类,反射的概念,Constructor,Field,Method,反射Main方法,数组的反射和实践
- JAVA进阶之旅(二)——认识Class类,反射的概念,Constructor,Field,Method,反射Main方法,数组的反射和实践
- Java深入(高新技术)(四):反射、Class、Constructor、Method、Field、数组的反射、JavaBean
- 浅谈Java中的反射机制以及Class、Constructor、Field、Method简单框架原理
- 黑马程序员-14-java-反射-反射概念及Field、Method、Constructor的应用
- Java反射之Class,Constructor,Field
- 黑马程序员--Java基础加强--16.利用反射操作泛型V【通过Constructor反射解析泛型构造方法】【通过Field反射解析泛型成员变量】【个人总结】
- java反射field和method的顺序问题
- Field,Method,Constructor— java 7 Reflection(三) 推荐
- java小结_018_反射Constructof_Method_field
- 黑马程序员——反射——Class、Constructor、Field、Method及简单框架原理
- Field,Method,Constructor— java 7 Reflection(三)
- 【反射】Reflect Class Field Method Constructor
- 【java】之Method和Field反射获取和设置属性值
- 黑马程序员------反射技术Constructor,Field,Method
- JAVA反射系列之Field,java.lang.reflect.Field使用获取方法。
- Java反射系列之Field
- java反射中getMethod getDeclaredMethod .
- JAVA反射系列之Field,java.lang.reflect.Field使用获取方法。