反射的基石:Claa类 Class代表的是类:即描述事物的共性
getName()
getPackage()
getMethods()
构造方法的反射
String st1= new String("abc");
Class cs1=Class.forName("java.lang.String");
Constructor ct1=String.class.getConstructor(StringBuffer.class);
String st2= (String)ct1.newInstance(new StringBuffer("acd"));
System.out.println(st2);
System.out.println(st2.charAt(2));
Field的例子
public class ReflectPoint {
private int x;
public int y;
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
}
ReflectPoint pt1=new ReflectPoint(3,5);
Field y=pt1.getClass().getField("y");
System.out.println(y.get(pt1));
Field x=pt1.getClass().getDeclaredField("x");
x.setAccessible(true);
System.out.println(x.get(pt1));
类的实例对象p得带对应的字节码 p.getClass()
Class 有个静态方法 Class.forName(“完整的类名”) 如java.lang.string
作业:将任意一个对象中的所有String类型的成员变量对应的字符串中的“b“改为”a“
待修改
import java.io.ObjectInput;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import org.omg.CORBA.Object;
public class ReflectTest {
public static void main(String[] args) throws Exception
{
ReflectPoint p1=new ReflectPoint();
changStringValue(p1);
System.out.println(p1);
}
public static void changStringValue(ReflectPoint s) throws Exception{
Field[] fields=s.getClass().getFields();
for(Field field:fields)
{if(field.getType()==String.class)
{
String oldvalue=(String)field.get(s);
String newvalue=oldvalue.replace("b", "a");
field.set(s, newvalue);
}
}
}
}
public class ReflectPoint {
public String str1="ball";
public String str2="basketball";
public String str3="itcast";
public String toString()
{
return str1+"+"+str2+"+"+str3;
}
}
package Lessson;
import java.lang.reflect.Field;
public class RelflectTest {
public static void main(String[] args)throws Exception
{
String st1="ball";
String st2="basketball";
String st3="itcast";
changeStringValue(st1);
changeStringValue(st2);
changeStringValue(st3);
}
public static void changeStringValue(Object obj)throws Exception
{
Field [] fields =obj.getClass().getFields();
for(Field field:fields)
{
if(field.getType()==String.class)
{
String oldvalue=(String)field.get(obj);
String newvalue=oldvalue.replace('b', 'a');
field.set(obj,newvalue);
}
}
}
}
Method类: 类里面的方法
String pp=new String("cdassrom");
Method mt=String.class.getMethod("charAt", int.class);
System.out.println(mt.invoke(pp, 1));
23.
String gg=args[0];
Method startingMethod=Class.forName(gg).getMethod("main",String[].class);
startingMethod.invoke(null,(Object)new String[]{"112","223","44423"});
为什么要这样调用main方法?
因为当只有参数的时候要去调用类,但是系统并不知道去调用哪个类,所以用这种方法找到类
具有相同维数和元素类型的数组属于同一类型,即具有相同Class的实例对象
基本类型的一维数组可以当作Object类型使用,不能当作Object【】类型使用:非基本类型的唯一数组,即可以当作Object类型使用,又可以当做Object【】类型使用
基本类型不是Object对象 所以int【】 不转换为Object【】
Arrays.asList()把数组按list打印出来 接受的参数是Object【】的数组
import java.lang.reflect.Array;
class ReflectTest
{
public static void main(String[] args)
{String []a1=new String[]{"aaa","bbb","ccc"};
int[] a2=new int[]{1,2,3,4,5,5,};
PrintObject(new String []{"aaa","bbb"});
}
private static void PrintObject(Object obj)
{
if(obj.getClass().isArray())
{
int len=Array.getLength(obj);
for(int i=0;i<len;i++)
{
System.out.println(Array.get(obj, i));
}
}
else
{
System.out.println(obj);
}
}
}
反射的综合案例
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
public class zonghe {
public static void main(String[] args) {
Collection collection1=new ArrayList();
Collection collection2=new HashSet();
ReflectPoint pt1= new ReflectPoint(3,5);
ReflectPoint pt2= new ReflectPoint(3,7);
ReflectPoint pt3= new ReflectPoint(3,5);
collection1.add(pt1);
collection1.add(pt2);
collection1.add(pt3);
collection1.add(pt1);
collection2.add(pt1);
collection2.add(pt2);
collection2.add(pt3);
collection2.add(pt1);
System.out.println(collection1.size());
System.out.println(collection2.size());
}
}
public class ReflectPoint {
/*public String str1="ball";
public String str2="basketball";
public String str3="itcast";
public String toString()
{
return str1+"+"+str2+"+"+str3;
}
*/
private int x;
private int y;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ReflectPoint other = (ReflectPoint) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
}
通过以上实例 比较ArrayList 和Hashset的区别
Arraylist针对相同值的对象,也放入,放入的位置不同
Hashset中如果有相同的对象,那么就不放入,或者把之前的覆盖
Hashset是类 Hashcode是方法
Hashset就是采用哈希算法存取对象的集合,它内部采用对某个数字N进行取余的方式对哈希码进行分组和划分对象的存储区域。
如果2个对象的equals相等,那么也要让其的hashcode也相等 这样相同的实例就不会重复的放在哈希集合中.
如果数据不放在哈希集合中,就不需要把哈希值也弄成相等
就散哈希的值的参数尽量不要去改变. 防止内存泄漏。
比如改变之后,想去删除该对象,但是之前计算哈希的值已经确定了,改变之后就找不到对象了,这样该对象就删除不了,占用了内存空间,但是没有被释放,发生内存泄漏。
反射的作用:实现框架的功能\
把程序要调用的类放在配置文件中配,在源程序中不要出现类名的调用
用反射的方法做:
配置文件的titile: config.properties
首现要配置 配置文件 工程目录右键 添加一个file文件
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Collection;
import java.util.Properties;
public class zonghe {
public static void main(String[] args) throws Exception{
InputStream ips=new FileInputStream("config.properties");//加载配置文件
Properties props=new Properties();//等效于一个hash map
props.load(ips);
ips.close();
String classname=props.getProperty("className");
Collection collection1=(Collection<ReflectPoint>)Class.forName(classname).newInstance();
/*Collection collection1=new ArrayList();
Collection collection2=new HashSet();*/
ReflectPoint pt1= new ReflectPoint(3,5);
ReflectPoint pt2= new ReflectPoint(3,7);
ReflectPoint pt3= new ReflectPoint(3,5);
collection1.add(pt1);
collection1.add(pt2);
collection1.add(pt3);
collection1.add(pt1);
/*collection2.add(pt1);
collection2.add(pt2);
collection2.add(pt3);
collection2.add(pt1);*/
System.out.println(collection1.size());
/*System.out.println(collection1.size());
System.out.println(collection2.size());*/
}
}
配置文件放在哪? getRealPath()得到项目路径 然后放下项目的下层目录里面
或者用类加载器加载
比如:
InputStream ips=ReflectTest2.class.getClassLoader().getResourceAsStream(“目录”);