——- android培训、java培训、期待与您交流! ———-
反射的基石。
判断是否为数组类型的Class实例对象的方法:Class.isArray();
public class Reflect_Class
{
public static void main(String[] args) throws Exception
{
String str1="abc";
Class cls1=str1.getClass();
Class cls2=String.class;
Class cls3=Class.forName("java.lang.String");
//这三个Class类的字节码是否为同一个呢?
System.out.println(cls1==cls2);//true;
System.out.println(cls2==cls3);//true;
System.out.println(cls3==cls1);//true;
//在虚拟中中存了一份字节码,而且这个字节码可以创建多个实例对象。
System.out.println(cls1.isPrimitive());//是否为基本类型的字节码?false,String不是基本类型,是一个类;
System.out.println(int.class.isPrimitive());//true;
System.out.println(int.class==Integer.class);//false;
System.out.println(int.class==Integer.TYPE);//Integer.TYPE打印就是它所包装的基本类型的字节码,因此为true;
System.out.println(int[].class.isPrimitive());//false;数组也是一种类型,有其对应的字节码,但是不是原始类型;
System.out.println(int[].class.isArray());//判断是不是数组;
}
}
public class ReflectDemo
{
public static void main(String[] args) throws Exception
{
//Constructor:
//new String(new StringBuffer("abc"));
//获取String类的字节码;
Constructor cons=String.class.getConstructor(StringBuffer.class/*,int.class*//*这里的StringBuffer传入的是一种类型*/);//方法中传入参数明确要获取的是哪个构造方法;之所以可以接收不同个数的参数,是因为JDK1.5的新特性(可变参数。)
//使用String类的字节码创建对象;
String str=(String) cons.newInstance(new StringBuffer("abc")/*这里的StringBuffer指的是传入的是StringBuffer类型的对象*/);//在编译的时候只知道是构造方法,但是不知道到底对应的是哪个构造方法,运行的时候才会知道到底对应的那个构造方法。
//第一个StringBuffer表示的是选择哪个构造方法,第二个StringBuffer指的是用这个StringBuffer的时候传一个StringBuffe的对象进去。
System.out.println(str.charAt(2));
//----------------------------------------------------------------------
//Filed:
ReflectPoint pt1=new ReflectPoint(3,5);
//得到一个字段:先得到类的字节码,
Field field_y=pt1.getClass().getField("y");
//获取y字段的具体值;field_y代表的是字节码变量,并不是对象身上的值,而是要用它去取对象对应的值。
System.out.println(field_y.get(pt1));
//Field field_x=pt1.getClass().getField("x");//java.lang.NoSuchFieldException: x//x是私有的,访问不到,只有被public修饰的成员变量才可以被访问到
//System.out.println(field_x.get(pt1));
//对于不可见的变量,也提供了一个获取方法:
Field field_x=pt1.getClass().getDeclaredField("x");
field_x.setAccessible(true);//设置访问权限;如果没有这一步,就会报java.lang.IllegalAccessException异常;
System.out.println(field_x.get(pt1));
//将任意一个对象中的所有String类型的成员变量所对应的字符串内容的"b"改"a";
changeStringValue(pt1);
System.out.println(pt1);
//---------------------------------------------------------------------------------
//Method:
//调用String类的charAt方法,用反射的形式实现;
Method methodCharAt=String.class/*String类的字节码*/.getMethod("charAt", int.class);//String类的字节码调用getMethod方法,第一个参数是要获取的那个方法的方法名,第二个参数是指要获取的那个方法的参数列表,一个类中的同名方法有多种重载形式,有多少个参数就在这里写多少个class.
System.out.println(methodCharAt.invoke(str, 1));//第一个参数是指在str上调用chatAt,第二个参数是指给charAt传入一个参数,上面有几个class就传几个参数;
//JDK1.4
System.out.println(methodCharAt.invoke(str, new Object[]{2}));//大括号中表示的是元素列表;这里的2表示传入了一个整数Object.其实就是装了一个Interger对象,这个对象的值是2;
//调用一个类的main方法;
//TestArguments.main(new String[]{"111","222","333"});//普通的调用方式,类直接调用该静态方法;
//String StartingClassName=args[0];
//Method mainMethod=Class.forName(StartingClassName).getMethod("main", String[].class);
//mainMethod.invoke(null,new Object[]{new String[]{"111","222","333"}});
//mainMethod.invoke(null,(Object)new String[]{"111","222","333"});
//------------------------------------------------------------------------------
//数组的反射:
int[] a=new int[]{1,2,3};
int[] b=new int[4];
int[][] c=new int[2][3];
String[] d=new String[]{"14","13","2"};
System.out.println(a.getClass()==b.getClass());//true;
//System.out.println(a.getClass()==c.getClass());
//System.out.println(a.getClass()==d.getClass());
System.out.println(a.getClass().getName());
System.out.println(a.getClass().getSuperclass().getName());//获取其父类;
System.out.println(d.getClass().getSuperclass().getName());
Object obja=a;
Object objb=d;
//Object[] objc=a;//基本数据类型不是Object;
Object[] objd=c;
Object[] obje=d;
System.out.println(a);
System.out.println(d);//哈希值;
//Arrays工具类,包含各种操作数组的静态方法;
System.out.println(Arrays.asList(a));//将数组的哈希地址值装进了List;
System.out.println(Arrays.asList(d));
//Array工具类用于完成对数组的反射操作;
//Object obj=null;
printObject(a);
printObject(d);
printObject("13");
}
private static void printObject(Object obj)
{
// TODO Auto-generated method stub
Class clazz=obj.getClass();
if(clazz.isArray())
{
int len=Array.getLength(obj);
for(int i=0;i
public class ReflectTest
{
public static void main(String[] args) throws Exception
{
/*getRealPath();//金山词霸/内部
一定要记住用完整的路径,但完整的路径不是硬编码,而是运算出来的。*/
//InputStream ips = new FileInputStream("config.properties");//读取config.properties文件;
//InputStream ips = ReflectTest.class.getClassLoader().getResourceAsStream("cn/itcast/day1/config.properties");
//InputStream ips = ReflectTest.class.getResourceAsStream("resources/config.properties");
InputStream ips = ReflectTest.class.getResourceAsStream("/cn/itcast/day1/resources/config.properties");
Properties props = new Properties();
props.load(ips);
ips.close();
String className = props.getProperty("className");
Collection collections = (Collection)Class.forName(className).newInstance();
//Collection collections = new HashSet();//3
//Collection collections = new ArrayList();//4
//区别:ArrayList是有序(位置顺序,来一个放一个)的集合,相当于一种数组;而HashSet会先判断有没有这个对象,没有就放进去,有就不放进去,
ReflectPoint pt1 = new ReflectPoint(3,3);
ReflectPoint pt2 = new ReflectPoint(5,5);
ReflectPoint pt3 = new ReflectPoint(3,3);
//如果要使pt1和pt3相同,就要去覆盖equals方法,不然他们有不同的hashCode值,属于不同的对象;
collections.add(pt1);
collections.add(pt2);
collections.add(pt3);
collections.add(pt1);
//pt1.y = 7; //将y的值存进去再改成7,频繁删除、添加、修改对象会发生内存泄露;
//collections.remove(pt1);
System.out.println(collections.size());//打印集合的大小;
}
}