黑马程序员--反射
来源:互联网 发布:汉邦尚品 知乎 编辑:程序博客网 时间:2024/06/02 05:14
------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
反射是什么?
反射就是把java类中的各种成分映射成相应的java类。例如,一个java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也要一个个java类来表示。表示java类的Class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,他们是Field,Method,Contructor,Package等等。
那么,如何获得一个类的Class对象呢?
获得javaClass对象的方法有三种,此处便拿String类作为示例:
String str = new String();
//类名.class
Class clazz1 = String.class;
//对象.class
Class clazz2 = str.getClass();
//Class类中的静态方法:forName(类名);
Class clazz3 = Class.forName("java.lang.String");
如果要加载的字节码已经被加载过,那么会直接返回那一份的字节码,如果没有加载过,那么jvm会把加载进来的字节码缓存起来。
在java中还有九个预定义实例对象:为八个基本类型和void
int double boolean sort char byte longfloat ,void
可以通过方法Class.isPrimitive()来判断是否为基本数据类型。
判断是否为数组:Class.isArray();
总之,只要在源程序中出现的类型都有各自的class实例对象,例如,int[],void
在比较字节码的时候用“==”胜过 equals(),因为比较的是两个Class对象用==来比较更加的合理。
Constructor类:
Constructor类代表某个类中的一个构造方法;
得到某个类的所有构造方法:
Constructor[] constructors =Class.forName("java.lang,String").getConstructors();
得到某一个构造方法:
Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
创建实例对象:
通常方式:String str =
newString(new StringBuffer("abc"));
反射方式:String str =
(String)constructor.newInstance(newStringBuffer("abc");
Class.newInstance()方法
例子:String obj =(String) Class.forName(“java.lang.String”).newInstance();
该方法先获得默认的构造方法,然后用该构造方法来创建实例化对象。
该方法内部的代码是怎么写的呢?
用到了缓存机制来保存默认的构造方法的实例对象。
实例:
package com.itheima;
import java.lang.reflect.Constructor;
public class ConstructorTest {
public static void main(String[] args) {
try {
Constructor con = Class.forName("java.lang.String").getConstructor(new StringBuilder().getClass());
String str = (String)con.newInstance(new StringBuilder("abc"));
System.out.println(str);
} catch (Exceptione) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
}
Field类:
Filed实例对象值代表类字节码中的一个变量,并不代表某一个对象里面的变量本身具体的值。我们需要调用Field类中的get(Object obj)方法。
Field类中的常用方法:
//获取所有public的Field对象。
getFields();
//非public成员获取Field对象(包括public)。
getDeclaredFields();
//暴力访问:
setAccessible(boolean flag);
//将指定对象变量上此 Field
对象表示的字段设置为指定的新值。
set
(Object obj,Object value);
//返回指定对象上此 Field
表示的字段的值。
get
(Object obj)
//返回一个 Class
对象,它标识了此 Field
对象所表示字段的声明类型。
getType();
Filed对象的使用:
Package com.itheima;
import java.lang.reflect.Field;
public class ChangeStringTest {
public static void changeStringValue(Objectobj){
//获得所有Field对象。
Field[] fields = obj.getClass().getDeclaredFields();
//取出Field集合中的元素。
for (Fieldfield : fields) {
//判断field类型是否为String,因为比较的是字节码文件 所有用==胜过equals();
if(field.getType()==String.class){
try {
//暴力访问。
field.setAccessible(true);
//使用一个字符串记录下field对象中String类型的值.
String oldValue = (String)field.get(obj);
//使用一个新字符串将旧字符串中的b替代为a。
String newValue =oldValue.replace('b','a');
//将newValue的值设置进obj中。
field.set(obj,newValue);
} catch (IllegalArgumentExceptione) {
// TODO Auto-generatedcatch block
e.printStackTrace();
} catch (IllegalAccessExceptione) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Test test = new Test();
changeStringValue(test);
System.out.println(test);
}
}
class Test{
public Stringstr1 = "ball";
public Stringstr2 = "basketball";
public Stringstr3 = "itcast";
private Stringstr4 = "byebye";
private Stringstr5 = "hellow";
public Test() {
// TODO Auto-generatedconstructor stub
}
@Override
public String toString() {
return"Test[str1=" + str1 +",str2=" + str2 +",str3=" + str3
+ ",str4=" + str4 + ",str5=" + str5 + "]";
}
}
Method类
Method类代表某个类中的一个成员方法。
得到类中的某一个方法:
Method charAt =
Class.forName("java.lang.String").getMethod("charAt",int.class);
java.lang.reflect.Method.invoke(Object obj,Object... args)
调用方法:
通常方式:System.out.println(str.charAt(1));
反射方式:System.out.println(charAt.invoke(str,1));
如果,传递给Method方法invoke为null,这意味着什么呢?
Method对象对应的是一个静态方法。
实例:
package com.itheima;
import java.lang.reflect.Method;
public class MethodDemo {
public static void main(String[] args) {
try {
String str = "itheima";
//通常方式。
System.out.println(str.charAt(3));
//反射方式
Method charAt =
Class.forName("java.lang.String").getMethod("charAt",int.class);
System.out.println(charAt.invoke(str, 3));
Method mainMethod = MethodTest.class.getMethod("main", String[].class);
//因为传给MethodTest的main方法为静态 所以传递给Method对象的invoke()方法的参数为null
//在给main方法传递参数的时候需要给String[]进行打包,使其不被解包。
//方法一:
mainMethod.invoke(null, (Object)new String[]{"abc","def","xyz"});
//方法二:
mainMethod.invoke(null,new Object[]{new String[]{"abc","def","xyz"}});
} catch (Exceptione) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
}
class MethodTest{
public static void main(String[] args) {
for (Stringarg : args) {
System.out.println(arg);
}
}
}
- 黑马程序员--java 反射
- 黑马程序员之反射
- 黑马程序员之反射
- 黑马程序员__java_反射
- 黑马程序员_反射
- 黑马程序员 反射
- 黑马程序员--Java反射
- 黑马程序员--反射
- 黑马程序员-java-反射
- 黑马程序员:反射技术
- 黑马程序员_java反射
- 黑马程序员---反射
- 黑马程序员-反射
- 黑马程序员---反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员:反射
- 黑马程序员_反射
- Relative与Absolute组合使用
- java源码分析之LinkedList
- yate学习--yateclass.h--class YATE_API Socket : public Stream
- Sublime Text3如何配置jshint插件(亲测可行)
- 关于asmack的packetwriter
- 黑马程序员--反射
- 通过Thread配置定时器
- HDOJ1059-Dividing(DP)
- 新OS快速安装常用开发包
- 使用IDA Pro调试so文件
- LeetCode 82之Remove Duplicates from Sorted List II的Java题解
- poj1063
- java中的几种排序总结
- 走私牛肉网上热卖 广西和广东成冻肉走私重灾区