黑马程序员Java培训和Android培训:反射

 

 

反射的基石: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(“目录”);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值