——- android培训、java培训、期待与您交流! ———-
反射的基石——Class类
java程序中各个java类属于同一类事物,描述这类事物的java类名就是Class。
人——>Person
java类——>Class
得到各个字节码对应的实例对象的三种方法
类名.class 例如: System.class
对象.getClass() 例如: new Date().getClass()
Class.forName(“类名”) 例如:Class.forName(“java.util.Date”);
package Reflect;
public class ReflectDemo {
public static void main(String[] args) throws ReflectiveOperationException {
//得到字节码的三种方法:
String str="abc";
Class cls1=str.getClass();
Class cls2=String.class;
Class cls3=Class.forName("java.lang.String");
System.out.println(cls1);
System.out.println(cls1==cls2);//是否指向同一个对象
System.out.println("是否是基本类型 : "+cls1.isPrimitive());
System.out.println(int.class);
}
}
反射就是把java类中各种成分映射成相应的java类。
Contructot类
*Constructor类代表某各类中一个构造方法
*得到某一个类所有构造函数
Constructot[] constructors=Class.forName(“java.lang.String).getConstructors();
*得到某一个构造方法
Contructor constructor=Class.forName(“java.lang.String”).getConstructor(String.class);
*创建实例对象
通常方式:String str=new String(new StringBuffer(“abc”));
反射方式: String str=(String)constructor.newInstance(new StringBuffer(“abc”));
调用获得的方法时要用到上面相同类型的实例对象
package Reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ConStructorDemo {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Constructor cons =String.class.getConstructor(StringBuffer.class);
String str2=(String) cons.newInstance(new StringBuffer("abc"));
System.out.println(str2);
}
}
Field类
Field类代表某个类中一个成员变量
package Reflect;
public class ReflectDemo1 {
private int x;
public int y;
public String str1="ball";
public String str2="basketball";
public String str3="itcast";
public ReflectDemo1(int x, int y) {
super();
this.x = x;
this.y = y;
}
//覆盖object中的tostring()方法,打印对象的时候会被自动调用
@Override
public String toString() {
return "ReflectDemo1 [str1=" + str1
+ ", str2=" + str2 + ", str3=" + str3 + "]";
}
}
package Reflect;
import java.lang.reflect.Field;
public class ReflectDemo2 {
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
ReflectDemo1 rfd= new ReflectDemo1(3,5);
Field fieldy =rfd.getClass().getField("y");
System.out.println(fieldy.get(rfd));
//暴力放射
Field fieldx=rfd.getClass().getDeclaredField("x");//可获得被私有化的的x
fieldx.setAccessible(true);//设置可见
System.out.println(fieldx.get(rfd));
//将任意一个对象中所有String类型的成员变量所对应的字符串内容中"b"改成"a".
changeStringValue(rfd);
System.out.println(rfd);
}
private static void changeStringValue(Object obj) throws IllegalArgumentException, IllegalAccessException {
Field[] fields=obj.getClass().getFields();
for(Field field:fields)
{
//field.getType().equals(String.class)
if(field.getType()==String.class)
{
String oldValue=(String) field.get(obj);
String newValue=oldValue.replace('b', 'a');
field.set(obj, newValue);
}
}
}
}
Method类
Method类代表某个类中一个成员方法
package Reflect;
import java.lang.reflect.Method;
public class MethodDemo {
public static void main(String[] args) throws Exception{
//得到方法名是charAt,参数类型是int的方法
Method methodcharAt =String.class.getMethod("charAt", int.class);
//用invoke()方法调用这个构造函数
System.out.println(methodcharAt.invoke("abc", 1));
}
}
用反射方式执行某个类中main方法
需求:写一个程序,这个程序能够根据用提供的类名,去执行该类中的方法。
package Reflect;
import java.lang.reflect.Method;
class TestArguments {
public static void main(String[] args) {
for(String arg: args)
{
System.out.println(arg);
}
}
}
public class MainTest {
public static void main(String[] args) throws Exception{
String[] s={"asd","43"};
Object[] o={s};
String startingClassName=args[0];
Method mainMethod=Class.forName(startingClassName).getMethod("main", String[].class);
mainMethod.invoke(null,o);
}
}
数组的反射
具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。
基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用,非基本类型的一维数组,即可以当作 Object类型使用,又可以当作Object[] 类型使用。
package Reflect;
import java.util.Arrays;
public class ArrayReflectDemo {
public static void main(String[] args) {
int[] a1=new int[]{1,2,3};
int[] a2=new int[4];
int[][] a3=new int[2][3];
String[] a4=new String[]{"a","b","c"};
System.out.println(Arrays.asList(a1));
System.out.println(Arrays.asList(a4));
}
}
反射的作用—>实现框架功能
package Reflect;
public class ReflectDemo1 {
private int x;
public int y;
public String str1="ball";
public String str2="basketball";
public String str3="itcast";
public ReflectDemo1(int x, int y) {
super();
this.x = x;
this.y = y;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((str1 == null) ? 0 : str1.hashCode());
result = prime * result + ((str2 == null) ? 0 : str2.hashCode());
result = prime * result + ((str3 == null) ? 0 : str3.hashCode());
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;
ReflectDemo1 other = (ReflectDemo1) obj;
if (str1 == null) {
if (other.str1 != null)
return false;
} else if (!str1.equals(other.str1))
return false;
if (str2 == null) {
if (other.str2 != null)
return false;
} else if (!str2.equals(other.str2))
return false;
if (str3 == null) {
if (other.str3 != null)
return false;
} else if (!str3.equals(other.str3))
return false;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
//覆盖object中的tostring()方法,打印对象的时候会被自动调用
@Override
public String toString() {
return "ReflectDemo1 [str1=" + str1
+ ", str2=" + str2 + ", str3=" + str3 + "]";
}
}
className=java.util.ArrayList
package Reflect;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Properties;
public class ReflectTest {
public static void main(String[] args) throws IOException, Exception, IllegalAccessException, ClassNotFoundException {
InputStream ips=new FileInputStream("E:\\elcipseworkspace\\demoproject\\src\\config.properties");
Properties props=new Properties();
props.load(ips);
ips.close();
String className=props.getProperty("className");
Collection coll=(Collection) Class.forName(className).newInstance();//利用反射,得到配置文件中ArrayList
//Collection coll=new HashSet();
ReflectDemo1 ref1=new ReflectDemo1(3,3);
ReflectDemo1 ref2=new ReflectDemo1(5,5);
ReflectDemo1 ref3=new ReflectDemo1(3,3);
coll.add(ref1);
coll.add(ref2);
coll.add(ref3);
coll.add(ref1);
// ref1.y =7;
//coll.remove(ref1);//这句并没有删除内存中的对象,会导致内存泄露。
System.out.println(coll.size());
}
}