反射深入学习
Class:java程序中的各个java类属于同一类事物,描述这类事物
java类名就是Class
创建字节码对象
1.类名.class 2.对象.getClass()3.Class.forName("类名");
String.class.isPrimitive()false不是基本数据类型的字节码对象
int.class.isPrimitive()true;
int.class== Integer.class false
int.class== Integer.TYPE true 包装类的TYPE属性包装着基本数据类型的字节码对象
数组类型的Class实例对象 Class.isArray()
Constructor类
得到某个类所有的构造方法
Constructor[]constructors = Class.forName("java.lang.String").getConstructors();
得到某一个构造方法:
Constructorconstructor =Class.forName("java.lang.String").getConstructor(StringBuffer.class);
Stringstr = (String)constructro.newInstance(new StringBuffer(""));
调用获得的方法时要用到相同类型的对象
Field
classRefectPoint{
privateint x;
publicint y;
publicRefectPoint(int x, int y) {
super();
this.x= x;
this.y= y;
}
}
classTest{
publicstatic void main(String[]args){
RefectPointre = new RefectPoint();
FieldfieldY = re.getClass().getField("y");
fieldY是某个类中的属性对象,而不是对象中的属性
要想取出y值,必须去取出某个对象中的值
fieldY.get(re);//y必须是共有的
Fieldfieldx = re.getClass().getDeclaredField("x");//获取私有变量
fieldx.setAccessable(true);
fieldx.get(re);
}
}
将一个对象中的String字段值,b用a代替
publicclass RefectPoint {
publicString str1 = "ball";
publicString str2 = "basketball";
publicString str3 = "sdutu";
publicString str4 = "haoao";
publicRefectPoint() {
super();
//TODO Auto-generated constructor stub
}
}
publicstatic void main(String[] args) throws Exception {
//TODO Auto-generated method stub
//将字符串的b改成a
StringclassName = "com.sdut.day1.RefectPoint";
//获取字节码对象
Classcls1 = Class.forName(className);
Field[]fields = cls1.getFields();
// Field field=cls1.getField("str2");
//创建某个对象
Objectobj = cls1.newInstance();
for(Fieldf:fields){
if(f.getType() ==String.class){//字节码用==比较。因为都是指String类的字节码对象,就一份
Stringstr = (String)f.get(obj);
str= str.replaceAll("b", "a");
f.set(obj,str);
System.out.println(f.get(obj));
}
}
}
Method
MethodmethodCharAt = String.class.getMethod("charAt",int.class);
methodCharAt.invoke(str1,1);
如果是methodCharAt.invoke(null,1);则charAt是静态方法
实例:
调用另一个类中main方法,执行
publicclass StaticPort {
publicstatic void main(String[] args) throws Exception {
String className ="com.sdut.day1.TestArguments";
Classc1 = Class.forName(className);
Methodm = c1.getMethod("main", String[].class);
m.invoke(null,new Object[]{new String[]{"a","b"}});//拆一层剩下的是参数
// m.invoke(null, (Object){new String[]{"a","b"}});//转为Object对象
}
}
classTestArguments{
publicstatic void main(String[]args){
for(Stringarg:args){
System.out.println(arg);
}
}
数组的反射
具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象
int[]a = new a[1]{1};
int[]b = new b[2];
int[][]c = new c[2][3];
String[]d = new String[4]{"a","b"};
a.getClass()== b.getClass();true;
a.getClass().getSuperclass().getName()//得到父类的名字
ObjectaObj1 = a1;
Ojbect[]aOjb2 = a1;//出错
Object[]cObj = c;//对,二维数组可以看成多个一维数组,每个一维数组可以转成Object对
Object[]dObj = d;//对,字符串也可以转为Object
ListArrays.asList(a);将int[]a对象转为Object对象放在List集合中
ListArrays.asList(d);将d中元素取出放在List集合中
asList(Objecto)1.4
asList(T...t)1.5
privatestatic void printObject(Object obj){
Classclazz = obj.getClass();
if(clazz.isArray()){
intlen = Array.getLength(obj);
for(inti = 0;i<len ;i++){
syso(Array.get(obj,i));
}
}
else{
syso(obj);
}
}
内存泄漏
原因:
当把元素根据hasCode(),equals()方法,加入集合后,
在集合外面修改某一个元素,会造成该元素的hasCode()
发生改变,删除时,根据hasCode找要删除的元素,就找不到
所以删不掉。
publicstatic void main(String[]args){
Collectioncollections = new HashSet();
RefectPointrp = new RefectPoint(2,3);
RefectPointrp1 = new RefectPoint(3,3);
RefectPointrp2 = new RefectPoint(2,3);
collections.add(rp);
collections.add(rp1);
collections.add(rp2);
collections.add(rp);
rp.y= 5;
collections.remove(rp);//删除不掉
System.out.println(collections.size());
}