黑马程序员_反射

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

 

Java程序中的各个Java类属于同一类事物,描述这类事物的Java类就是Class。

Class类代表Java类,它的各个实例对象对应各个类在内存中的字节码。

一个类被类加载器加载到内存中,占用一片内存空间,这个空间里面的内容就是类的字节码,

不同的类的字节码是不同的,所以他们在内存中内容是不同的,这一个个空间可以分别用一个

个对象来表示,这些对象显然具体有相同的类型。

---------------------------------------------------------------------

如何得到各个字节码对应的实例对象(Class类型)

1.类名.class,例如   System.class

2.对象.getjClass(),例如 new Date().getClass()

3,Class.forName("类名"), 例如  Class.forName("java.util.Date"):  //这种用得比较多

一共有九个预定义Class实例对象:八个基本数据类型和 void.class

int.class == Integer.TYPE

数组类型的Class实例对象是  Class.isArray()

总之,只要在源程序中出现的类型,都有各自的Class实例对象,例如int[].class     void.class

---------------------------------------------------------------

例子:

String str1 = "abc";
  Class cls1 = str1.getClass();
  Class cls2 = String.class;
  Class cls3 = Class.forName("java.lang.String");
  System.out.println(cls1 == cls2);       //ture
  System.out.println(cls1 == cls3);  //ture
  
  System.out.println(cls1.isPrimitive());  //false
  System.out.println(int.class.isPrimitive());  //true
  System.out.println(int.class == Integer.class);  //false
  System.out.println(int.class == Integer.TYPE); //true
  System.out.println(int[].class.isPrimitive()); //false
  System.out.println(int[].class.isArray());  //true

---------------------------------------------

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

构造方法的反射:Constructor类

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

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

Constructor[] constructors = Class.forName("java.lang.String").getConstructors();

得到某一个构造方法:

Construtor constructor = Class.forName("java.lang.String").getConstructors(StringBuffere.class);

创建实例对象:

通常方式:String str = new String(new StringBuffer("abc"));

反射方式:String str = (String)constructor.newInstance(new StringBuffer("abc"));

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

--------------------------------------------

Class.newInstance()方法:

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

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

该方法内部的具体代码是用到了缓存机制来保存默认构造方法的实例对象。

说明,反射中创建实例是比较消耗资源的。

-------------------------------------------------

成员变量的反射:Field类

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

例子:

ReflectPoint pt1 = new ReflectPoint(3,5);

Field fieldY = pt1.getClass().getField("y");
  //fieldY不是对象身上的变量,而是类上,要用它去取某个对象上对应的值
  System.out.println(fieldY.get(pt1));

//  通过get方法取出具体值
  Field fieldX = pt1.getClass().getDeclaredField("x");

// 因为x变量时private的,所以要用 getDeclaredField("x")     
  fieldX.setAccessible(true);

// 称为暴力取出,  如果没有setAccessible(true)  则不能取出x 的具体值
  System.out.println(fieldX.get(pt1));

例子:

private static void changeStringValue(Object obj) throws Exception {
  Field[] fields = obj.getClass().getFields();
  for(Field field : fields){
      if(field.getType() == String.class){      //因为是同一个字节码文件,所以用==比equals更专业
    String oldValue = (String)field.get(obj);
    String newValue = oldValue.replace('b', 'a');
    field.set(obj, newValue);
   }}}}
  ----------------------------------------------------------

成员方法的反射:Method类

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

得到类中的某一个方法:

Method charAt = Class.forName("java.lang.String").getMethod("charAt", int.class);

调用方法:

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

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

如果传递给Mothod对象的invoke()方法的第一个参数为null,说明该方法对象对应的是一个静态方法。

例子:

Method methodChatAt = String.class.getMethod("ChatAt", int.class);

System.out.println(methodChatAt.invoke(str1, 1));  //取出str1对象中的第1个字母

---------------------------------------------------------------------------------------

用反射方式执行某一个类中的卖main方法:

用处:能够根据用户提供的类名,去执行该类中的main方法。

例子:

String startingClassName = args[0];

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

mainMethod.invoke(null, new Object[]{new String[]{"111","222","333"}});// 参数null表示方法时静态的。

----------------------------------------------------

数组的反射:

具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。

代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class。

基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用。

非基本类型的一维数组,既可以当做Object类型使用,又可以当做Object[]类型使用。

Array工具类用于完成对数组的反射操作。Array在long.reflect的包中.

问题:给一个数组,把数组内容打印出来。

代码实现:

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);
  }
 }

--------------------------------------

数组反射中的例子:

int [] a1 = new int[]{1,2,3};
  int [] a2 = new int[4];
  int[][] a3 = new int[2][3];
  String [] a4 = new String[]{"a","b","c"};
  System.out.println(a1.getClass() == a2.getClass());     //true
  System.out.println(a1.getClass() == a4.getClass());     //false
  System.out.println(a1.getClass() == a3.getClass());    //false


  System.out.println(a1);//对象内存地址
  System.out.println(a4);//对象内存地址
  System.out.println(Arrays.asList(a1)); 

//Arrays.asList方法接收的参数是Object[]  

//把a1当成是一个对象,因为a1里面的是基本数据类型
  System.out.println(Arrays.asList(a4)); 

//把a4拆包,当成是多个对象。

-------------------------------------------------- 

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

框架与工具类的区别:工具类被用户的类调用,而框架则是调用用户提供的类。

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

例子:

new一个File 配置文件,写成一个Properties文件,然后把文件通过io加载进类 如:className = java.util.ArrayList

InputStream ips = new FileInputStream("config.properties");

  Properties props = new Properties();
  props.load(ips);
  ips.close();
  String className = props.getProperty("className");
  Collection collections = (Collection)Class.forName(className).newInstance();

 

 

 

 ------- android培训java培训、期待与您交流! ----------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python是一种编程语言,而"黑马程序员"是一个培训机构。在Python中,可以使用print语句来输出文本。例如,通过运行以下代码:print("零基础,学Python, 月薪过万,就来黑马程序员。"),可以将"零基础,学Python, 月薪过万,就来黑马程序员。"这个文本输出到屏幕上。 除了输出文本,Python还可以定义变量并进行打印,例如:a = 666,b = 3.14,c = "零基础,学Python, 月薪过万,就来黑马程序员。",然后使用print语句打印这些变量。 无论是输出文本还是打印变量,在Python中都可以使用print语句来实现。同时,注释是在代码中用来解释和说明代码的部分,通过注释可以提供对代码的理解和解释。所以,如果你想在Python程序中输出"黑马程序员",你可以使用print语句来实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [黑马程序员最新Python教程——第一阶段(1)](https://blog.csdn.net/weixin_46225503/article/details/126850291)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [黑马程序员---Python高级技巧编程](https://blog.csdn.net/qq_45893319/article/details/129965089)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值