黑马程序员_基础加强2

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IO开发S</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

         反射

       一:得到字节码有2种情形

        1.类已经加载进内存,要得到它只要找到它将其放回即可

        2.在java虚拟机中还没有字节码,就要用类加载器去加载,加载后将字节码缓存起来,同时,用forName()放回加载的字节码.

      二:得到字节码的实例对象有3种方式(class类型)

         1.类名.class;

         2.对象.getclass();
    3.Class.forName();有9个预定义的Class对象,即8个基本数据类型+void类型

    有几个重要的方法:

    isPrimitive();判断是否是原始类型

    isArray();判断是否是数组

        Type可以将包装类型转成基本类型,如:int.class = Integet.Type;

        三.对构造函数的反射

   public class ReflectDemo {

 /**
  * @param args
  * @throws Exception
  * @throws NoSuchFieldException
  * @throws Exception
  * @throws NoSuchMethodException
  * @throws Exception
  */
 public static void main(String[] args) throws NoSuchFieldException, Exception  {
  /*String str = "asc";
  Class clazz1 = str.getClass();
  Class clazz2 = String.class;
  Class clazz3 = null;
  try {
   clazz3 = Class.forName("java.lang.String");
  } catch (ClassNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  System.out.println(clazz1==clazz2);
  System.out.println(clazz2==clazz3);*/
  
  //new String(new StringBuffer("qwe"));
  /*Constructor constructor = String.class.getConstructor(StringBuffer.class);
  String str =(String)constructor.newInstance(new StringBuffer("qwe"));
  System.out.println(str.charAt(3));*/
  ReflectPoint reflectpoint = new ReflectPoint(3, 5);
  Class ref = reflectpoint.getClass();
  Field filedy = ref.getField("y");
  Field filedx = ref.getDeclaredField("x");   //私有的,用获取所有字段方法
  filedx.setAccessible(true);  //设置字段可见,实现暴力反射
  System.out.println(filedy.get(reflectpoint));
  System.out.println(filedx.get(reflectpoint));
 }

}

        四.对成员字段的反射

public class ReflectDemo1 {

 /**
  * @param args
  * @throws Exception
  * @throws IllegalArgumentException
  */
 public static void main(String[] args) throws IllegalArgumentException, Exception {
  ReflectDemo reflectDemo = new ReflectDemo();
  
  Class clazz = Class.forName("cn.itcast.ReflectPoint");
  Field[] fields = clazz.getDeclaredFields();
  for (Field field : fields) {
   if (field.getType()==String.class) {  //判断是否是String类型,可能是同一个字节码,因此用等号判断
    String oldStr = (String)field.get(reflectDemo);
    String newStr = oldStr.replace("a", "b");
    field.set(reflectDemo, newStr);
   }
  }
  
  

 }

}

        五.对方法的反射

public class MethodReflect {

 /**
  * @param args
  * @throws Exception
  */
 public static void main(String[] args) throws Exception {
  Class clazz = Class.forName("cn.itcast.reflectpoint");
  Method method = clazz.getMethod("getX");
  method.invoke(ReflectPoint.class); 
  System.out.println(method);
 }

}

       六:数组与Object的关系及反射类型

       1.数组具有相同的类型(如int)并且有相同的维度时(同是一维或同是二维),他们的字节码相同

       2.基本类型的一维数组不能转换成Object的数组,例:

import java.util.Arrays;

public class ArrayReflect {

 /**
  * @param args
  */
 public static void main(String[] args) {
  /*int[] arr1 = new int[2];
  int[] arr2 = new int[3];
  int[][]arr3 = new int[2][3];
  String [] arr4 = new String[4];
  System.out.println(arr1.getClass()==arr2.getClass());
  //System.out.println(arr1.getClass()==arr4.getClass());
  //System.out.println(arr1.getClass()==arr3.getClass());
  System.out.println(arr1.getClass().getSuperclass().getName());
  Object object1 = arr1;
  Object object2 = arr2;
  Object[] objects3 = arr3;
  Object[] objects4 = arr4;*/
  //Object[] objects5 = arr1;
  //Object[] objects6 = arr2; 
  int[] ar1 = new int[]{3,4,7,2};
  String[] ar2 = new String[]{"qwe","ff","ww"};
  System.out.println(Arrays.asList(ar1));
  System.out.println(Arrays.asList(ar2));
  
 }

}

        七:内存泄露问题

            当一个对象被存储进HashSet集合后,就不能修改这个对象中那些参与计算的哈希值字段,否则被修改后的哈希值与最初被存进HashSet集合中的哈希值就不一样了,在这种情况下,无法对对象的当前引用进行删除,造成内存泄露.

         八:反射的作用:实现框架功能

             框架要解决的核心问题:

             在写程序的时候无法知道要被调用的类名,所以在写程序时无法直接new某个类的实例对象,因此要用反射的方式来做,例:

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Collection;
import java.util.Properties;

public class FrameReflectDemo {

 /**
  * @param args
  * @throws Exception
  * 用类加载器加载配置文件
  */
 public static void main(String[] args) throws Exception {
  //InputStream in = new FileInputStream("config.propertise");
  InputStream in = FrameReflectDemo.class.getResourceAsStream("config.propertise");
  Properties propes = new Properties();
  propes.load(in);
  in.close();
  String className = propes.getProperty("className");
  Collection collection =(Collection)Class.forName(className).newInstance();
  collection.add(new ReflectPoint(3, 5));
  collection.add(new ReflectPoint(4, 3));
  collection.add(new ReflectPoint(2, 8));
  System.out.println(collection.size());
  
 }

}         
       八:其他

        反射:就是把java类中的各种成分映射成相应的java类,编译器只看变量的的定义,不看代码的执行.

        反射会导致程序性能的下降,因为里面缓存了构造方法.

        为什么要用反射的方式调用函数?因为在执行前比昂不知到要执行那个类.

        成员方法的反射:当对象设置为null时,说明它调用的是一个静态方法

        取得私有的构造函数,变量或方法时,需要用到暴力反射

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IO开发S</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

    

      

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值