黑马程序员--21--高新技术(二)

------- android培训java培训、期待与您交流! ----------

反射

反射就是把java类中的各种成分映射成相应的java类。

例如:一个java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,修饰符、包等信息用一个个的java类来表示。

//编译器只看变量的定义不看代码的执行

l Constructor 类代表某个类中的一个构造方法

1)得到某个类所有的构造方法:

例子:

Constructor[] constructors =

Class.forName(“java.lang.String”).getConstructor();

//class—>constructor-->new object

 

2)得到某一个构造方法:

例子:

Constructor constructor =

Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);

 

3)创建实例对象

通常方式:String str = new String(new StringBuffer(“abcd”));

反射方式:String str =

(String)constructor. newInstance(new StringBuffer("abc"));

//调用获得的方法时要用到上面相同类型的实例对象

4Class.newInstance()方法

例子:String obj = (String) Class.forName(“java.lang.String”).newInstance();

该方法内部先得到默认的构造方法,然后用构造方法创建实例对象。

用缓存机制保存默认构造方法的对象。

 

new String(new StringBuffer("abc"))

Constructor constructor = String.class.getConstructor(StringBuffer.class);//表示选择了哪个构造方法(类型)

String str2=(String) constructor.newInstance(new StringBuffer("abc"));//表示用这个构造方法时,传递的StringBuffer对象(同样类型的对象)

System.out.println(str2.charAt(1));

 

 

l Field类代表某个类中的一个成员变量

 

 

ReflectPoint pt1 = newReflectPoint(3, 5);

Field fieldY = pt1.getClass().getField("y");

//fieldY代表类字节码中的变量,不是对象本身的变量,而是类上,要用它去取某个对象的值

System.out.println(fieldY.get(pt1));

 

Field fieldX = pt1.getClass().getDeclaredField("x");

fieldX.setAccessible(true);//暴力反射(变量为私有)看见了取不到用暴力反射

System.out.println(fieldX.get(pt1));

 

实例:

public class ReflectPoint {

privateint x;

publicint y;

 

public String str1 ="ball";

publicString str2 = "basketball";

publicString str3 = "itcast";

//自动生成构造函数

publicReflectPoint(intx, inty) {

super();

this.x= x;

this.y= y;

}

 

}

 

private static void changeStringValue(Object obj) throwsIllegalArgumentException, IllegalAccessException {

Field[] fields = obj.getClass().getFields();

for(Field field:fields){

//iffield.getType().euqals(String.class)

//因为是同一份字节码

if(field.getType()==String.class) {

String oldValue = (String)field.get(obj);

String newValue = oldValue.replace('b','a');

field.set(obj, newValue);

}

}

 

}

 

l Method类代表某个类中的一个成员方法

1)得到类中的某一个方法:

例子:Method charAt =

Class.forName(“java.lang.String”).getMethod(“charAt”,int.class);

2)调用方法

通常方式:System.out.println(str.charAt(1));

反射方式:System.out.println(charAt.invoke(str,1));

如果传递给method对象的invoke()方法的第一个参数为null,则该method对象对应的是一个静态方法!

3)Jdk1.4jdk1.5invoke方法的区别(可变参数)

 

//拿出字节码的方法再作用于某个对象

Method methodCharAt = String.class.getMethod("charAt",int.class);

System.out.println(methodCharAt.invoke(str1, 1));

//jdk1.4的调用方法

System.out.println(methodCharAt.invoke(str1,newObject[]{2}));

//1.5 可变参数

methodCharAt.invoke(Object obj,O bject[] args);

 

对接收数组参数的成员方法进行反射

u 用反射方式执行某个类中的main方法

 

class TestArguments {

publicstatic voidmain(String[] args) {

for(String arg :args){

System.out.println(arg);

}

 

}

 

//调用main方法

//TestArguments.main(new String[]{"123","345","sss"});

 

//用反射去调用

String startingStringClassName = args[0];

Method mainMethod = Class.forName(startingStringClassName).getMethod("main", String[].class);

mainMethod.invoke(null, new Object[]{new String[]{"ss","123"}});

 

mainMethod.invoke(null,(Object)newString[]{"ss","123"});

 

l 数组的反射

元素类型相同与维数相同 属于同一类型,具有相同的Class实例对象

注意:基本类型的一维数组可以被当作Object类型使用,不能当作能当作Object[]类型使用;非基本类型的一维数组,既可以当做Object类型使用,又可以做Object[]类型使用。

Arrays.aslist()方法处理intString[]时的差异--

 

不能得到整个数组的类型 可以得到某个值的类型

例子:a[0].getClass().getName();

 

//数组

int[] a1 =new int[3];

int[] a2 =new int[4];

int[][] a3 =new int[2][3];

String[] a4 =new String[]{"ad","bd","cd"};

 

System.out.println(a1.getClass()==a2.getClass());

//System.out.println(a1.getClass()==a4.getClass());

//System.out.println(a1.getClass()==a3.getClass());

System.out.println(a1.getClass().getName());

System.out.println(a1.getClass().getSuperclass().getName());

System.out.println(a4.getClass().getSuperclass().getName());

 

ObjectaObj1 = a1;

ObjectaObj2 = a4;

//Object[] aObj3 = a1; int不是object

Object[]aObj4 = a3;

Object[]aObj5 = a4;

System.out.println(a1);

System.out.println(a4);

System.out.println(Arrays.asList(a1));//一个参数

System.out.println(Arrays.asList(a4));

 

printlnObject(a4);

printlnObject(123);

 

privatestatic voidprintlnObject(Object obj) {

Class clazz = obj.getClass();

if(clazz.isArray()) {

intlen = Array.getLength(obj);

for(inti = 0; i < len; i++) {

System.out.println(Array.get(obj, i));

}

}else {

System.out.println(obj);

}

 

l ArrayList_HashSet的比较及Hashcode分析

Arraylist 是否相同都存入引用

Hashset 如果集合中有则不存入。

Hashcode 的作用:每个集合分区域哈希值对应区域(提高查找效率)提高对集合操作的效率 (内存泄漏) (内存一直被占用)

 

l 反射的作用--->实现框架功能

框架:别人调用你的类

框架要解决的核心问题:利用反射

 

InputStream ips= newFileInputStream("config.properties");

Properties ps =new Properties();

ps.load(ips);

ips.close();

String className = ps.getProperty("className");

Collection collections = (Collection)Class.forName(className).newInstance();

 

GetRealPath

得到资源文件的方法??

 

u 内省 introSpector --->javaBean-->特殊的java

javaBean 是一种特殊的java类,主要用于传递信息,这种类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。

JavaBean的属性根据方法名得出

Age -->如果第二个字母是小写,则第一个字母变成小的—>age

gettime-->time

getTime-->time

getCPU--->CPU

例:public class IntroSpectorTest {

 

 

publicstatic voidmain(String[] args) throwsException{

//TODO Auto-generated method stub

ReflectPoint pt1 =new ReflectPoint(3,4);

String propertyName ="x";

//x-->X-->getX-->MethodGetX

PropertyDescriptor pd =new PropertyDescriptor(propertyName, pt1.getClass());

Method methodGetX =pd.getReadMethod();

Object retVal =methodGetX.invoke(pt1, args);

System.out.println(retVal);

 

Object retVal1=getProperty(pt1, propertyName);

System.out.println(retVal1);

 

Method methodSetX = pd.getWriteMethod();

methodSetX.invoke(pt1, 7);

System.out.println(pt1.getX());

 

Object value = 9;

setProperty(pt1, propertyName, value);

System.out.println(pt1.getX());

 

 

}

 

privatestatic voidsetProperty(Object pt1,String propertyName,Object value)throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{

PropertyDescriptor pd2 =new PropertyDescriptor(propertyName, pt1.getClass());

Method methodSetX = pd2.getWriteMethod();

methodSetX.invoke(pt1, value);

}

privatestatic Object getProperty(Object pt1,String propertyName1) throwsException{

BeanInfo beanInfo =Introspector.getBeanInfo(pt1.getClass());//javaBean来看这个类

PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();//得到属性描述

Object retValu =null;

for(PropertyDescriptor pd:pds){

if(pd.getName().equals(propertyName1)){

Method methodGet =pd.getReadMethod();

retValu = methodGet.invoke(pt1);

break;

 

}

 

}

returnretValu;

}

 

}

------- Windows Phone 7手机开发 .Net培训 、期待与您交流! -------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值