------- android培训、java培训、期待与您交流! ----------
反射的基石——Class类
Class类代表java类,它的各个实例对象分别对应各个类在内存中的字节码
字节码 :一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的
类的字节码是不同的,所有他们在内存中的内容也是不一样的,这些对象显然具有相同的类型,这个类型就是Class,
例如
人--Person
java类--Class
Person p1=new Person();
Class clazz1 =System.class; //用类名.class获取一个类的字节码
Class clazz2 = p1.getClass(); //调用对象的getClass()方法可以得到
Class clazz3 = Class.forName(“java.util.Date”);
Class.forName()返回方式有两种,一种是曾经被加载过,缓存在java虚拟机中,直接返回,另一种java虚拟机中还没有,类加载器加载,然后缓存在java虚拟机中,以后直接返回
九个预定义Class实例对象:8个基本的 Java 类型(boolean、byte、char、short、int、long、float 和double)和关键字void表示为Class对象。 基本类型的字节码获取方式只有一种就是类名.class。例如int.class;
void.class
int.class==Integer.TYPE
数组类型的Class实例对象
class.isArray();
总之,只要是在源程序中出现的类型,都有各自的Class实例对象,例如int[],void
反射
反射就是把Java类中的各种成分映射成相应的Java类。例如:一个Java类中用一个Class类的对象来表示,一个
类中的组成部分:成员变量,方法,构造方法,包等信息也用一个个的Java类来表示,就像汽车是一个类,汽车
中的发动机,变速箱等也是一个个类。表示Java类的Class类显然要提供一系列的方式,来获得其中的变量,方
法,构造方法,修饰符,包等信息,谢谢信息就是用相应类的实例对象来表示的,它们是:Field、Method、
Contrctor、Package等等
Constructor类
例子:Constructor[] constructors=Class.forName("java.lang.String").getConstructors();
得到每个构造方法:
例子:Constructor[] constructor=Class.forName("java.lang.String").getConstructor(StringBuffer.class);
Field类
得到类中的成员变量方法
Field[ ]fields =clazz.getFields()
Field [ ]fiels = clazz.getDeclaredFields()如果成员变量类型是private类型
Field field = clazz.getField("成员变量名")
Field fiel = clazz.getDeclaredField("成员变量名")
Method类
得到类中的某一个方法
例子
Method charAtmethod=String.class.getMethod("charAt",int.class);
调用方法
charAtmethod.invoke(str.1)//str.charAt(1);
数组的反射
具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。
代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class。
基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用;非基本类型的一维数组,既可以当做Object类型使用,又可以当做Object[]类型使用。
int[ ] a1= new int[3];intp[ ]a2=new int[4];int[ ][ ]a3=new int[2][3];String[ ]a4=new String[4];Object obj1=a1;Object obj2=a4l;//Object[ ]obj3=a1;Object [ ]obj4=a3;Object[ ]obj5=a4;
以上知识点代码如下
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;
public class ReflectTest {
/**
* @param args
*/
public static void main(String[] args) throws Exception{
Constructor[]constructors = Class.forName("java.lang.String").getConstructors();
for(Constructor constructor:constructors){
String name = constructor.getName();
Class[] clazzs = constructor.getParameterTypes();//获取参数类型
for(Class clazz : clazzs){
String paramname = clazz.getName();
System.out.println("name"+name+" paramname "+paramname);
}
System.out.println("下一个");
}
Constructor constructor1 = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
//String s = new String(new StringBuffer("abc"));
String s= (String)constructor1.newInstance(new StringBuffer("abc"));
System.out.println(s.charAt(2));
ReflectPoint p = new ReflectPoint(2,4);
Field fieldY = p.getClass().getField("y");//fieldY 不是对象身上的变量,而是类上的,要用它去取某个对象对应的值
System.out.println(fieldY.get(p));
//爆力反射,因为x是private类型,
Field fieldX = p.getClass().getDeclaredField("x");
fieldX.setAccessible(true);
System.out.println(fieldX.get(p));
changeStringValue(p);
System.out.println(p);
Method methodCharAt=String.class.getMethod("charAt",int.class);
System.out.println(methodCharAt.invoke(s,1));
Method mainMethod =TestAgruments.class.getMethod("main", String[].class);
mainMethod.invoke(null,(Object)new String[]{"11","122","33"});
//new Object[]{new String[]{"11","122","33"}};1.5会自动拆箱一次,所有给他家一层
System.out.println(args[0]);
String str = "abcd";
String[]s1 =new String[]{"a","b","c"};
printObject(str);
printObject(s1);
}
private static void printObject(Object obj) {
Class clazz = obj.getClass();
if(clazz.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);
}
}
private static void changeStringValue(Object obj)throws Exception {
Field []fields = obj.getClass().getFields();
for (Field field : fields){
if(field.getType()== String.class){
String oldString=(String)field.get(obj);
String newString=oldString.replace('c', 'x');
field.set(obj,newString);
}
else
System.out.println(111111);
}
}
}
class TestAgruments{
public static void main(String[] args) {
}
}
import java.lang.reflect.*;
public class ReflectPerson {
/**
* @param args
*/
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
Class clazz = Class.forName("Person");
Person p = (Person)clazz.newInstance();
Method method=clazz.getMethod("setName", String.class);
method.invoke(p,"xxt");
Method method1=clazz.getMethod("setAge", int.class);
method1.invoke(p,21);
System.out.println(p.toString());
}
}
public class ReflectPoint{
String s = "aabbcc";
public String s1 ="cbcca";
private int x;
public int y;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public ReflectPoint(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 + 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;
final ReflectPoint other = (ReflectPoint) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
public String toString(){
return s+";"+s1;
}
}
框架
我做的房子卖给用户主,由用户自己安装门窗和空调,我做的房子就是框架,用户需要使用我的框架,把门插入我提供的框架中。框架与工具有区别,工具类被用户的类调用,而框架则是调用用户提供的类。框架要解决的核心问题
我在写框架(房子)时,你这个用户可能还在上小学,还不会写程序,我写的框架程序怎么调用到你以后写的类(门窗)呢?因为在写程序时无法知道要被调用的类名,所有,在程序中无法直接new某个类的实例对象,而需要用反射方式来做
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Properties;
public class ReflectTest2 {
/**
* @param args
*/
public static void main(String[] args)throws Exception {
InputStream in = new FileInputStream("config.properties");
Properties pro = new Properties();//Properties对象可以加载硬盘上的信息,已键值对存在
pro.load(in);
in.close();
String className=pro.getProperty("className");
Collection collection = (Collection)Class.forName(className).newInstance();//用反射方式调用无参的构造方法
//Collection collection =new HashSet();
ReflectPoint p1 = new ReflectPoint(2,2);
ReflectPoint p2 = new ReflectPoint(3,3);
ReflectPoint p3 = new ReflectPoint(4,4);
ReflectPoint p4 = new ReflectPoint(4,4);
collection.add(p1);
collection.add(p2);
collection.add(p3);
collection.add(p4);
System.out.println(collection.size());
}
}