`
qq272936993
  • 浏览: 3189 次
社区版块
存档分类
最新评论

黑马程序员_java基础反射

阅读更多

java程序中各个java类属于同一类事物,描述的java类名就是Class.

 

Class类代表java类,它的各个实例对象又分别对应什么呢?

       1.对应各个类在内存中的字节码。

       2.一个类呗类加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码.不同的类的字节码

是不同的.这一个个的空间可分别用一个个对象来表示.

 

Class与class的区别:

      Class就是一个类,而class是java语言关键字,class也是每个类的成员变量.

 

Class类描述了哪方面的信息?

     类的名字,类的访问属性,类所属的包名,字段名称的的列表,方法名称的列表.等等。

 

 

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

       类名.class,例如:People.class;

       对象.getClass(),例如: new Date().getClass();

       Class.forName("类名"),例如 : Class.forName("java.util.Date");

 

九个预定义的Class对象(有九种预定义的 Class 对象,表示八个基本类型和 void。这些类对象由 Java 虚拟机创建,与其表示的基本类型同名,即 boolean、byte、char、short、int、long、float 和 double)

       参看: Class.isPrimitive() 方法帮助(eg: int.class.isPrimitive()   true)

       int.class == Interge.TYPEtrue

       基本类型数组不是已定义Class对象,所以int[].class.isPrimitive();    false

 

总之,只要是在源程序中出现的类型,都是有各自的Class实例对象.

 

 

反射:就是把java类中的各种成分映射成相应的java类。表示java类的Class类显然是提供一系列的方法,来获取其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应的实例对象来表示,他们是Field、Method、Contructor、Package扥等。

 

 

Constructor类:代表某个类张的一个构造方法.

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

        eg: Constructor constructors[] = Class.forName("java.lang.String").getConstructor(StringBuffer.class);

 

得到某一个构造方法:

       eg: constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);

 

创建实例对象:

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

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

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

 

Class.newInstance()方法:

       该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象,用到了缓存机制来保存默认构造方法的实例对象.

 

 

思维拓展:

        new 和newInstance()的区别:

               首先,newInstance()是一个方法,而new是一个关键字。

               其次,Class下的newInstance()的使用有局限,因为它生成对象,只能调用无参构造函数,而是用new关键字生成对象没有限制.

 

 

Field类:

 

public class ReflectPoint {

	private int x;
	public int y;
	
	public ReflectPoint(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}


	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}


	public int getX() {
		return x;
	}


	public void setX(int x) {
		this.x = x;
	}
	
}


 

public class TestRun {
	
	public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
		ReflectPoint ptl = new ReflectPoint(3, 5);
		//fieldY不是对象身上的变量,而是类上的,要用它去取某个对象上的值
		
		//说明getFields只是获取public修饰的成员变量/getField也一样.
		Field[] publicFields= ptl.getClass().getFields();	
		for(Field f : publicFields){
			System.out.println(f.toString()+"\t"+f.get(ptl));
		}
		
		System.out.println("===================================>");
		//说明getDeclaredField会获取所有的成员变量/getDeclaredField也一样
		Field[] privateFields = ptl.getClass().getDeclaredFields();
		for(Field f : privateFields){
			f.setAccessible(true);
			System.out.println(f.toString()+"\t"+f.get(ptl));
		}
		System.out.println("==================================>");
		
		
		Field fieldX = ptl.getClass().getDeclaredField("x");
		fieldX.setAccessible(true);	//设置访问权限,常常对private修饰的属性设置
		System.out.println(fieldX.get(ptl));
	}
}

 

 

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

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

 

jdk1.4和jdk1.5的invoke方法的区别:

      jdk1.5:public invoke(Object obj,Object ... args);

      jdk1.4:public invoke(Objcet obj,Object[] args);

 

 

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

      由于jdk1.5的,参数为Object...,然而main方法需要传递的为数组,所有通过invoke()只会认为是1.4的写法.

 

解决办法:

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

       mainMethod.invoke(null,(Object)new String[]{"XXXX"}),编译器会特殊处理,翻译时不把参数当做数组看待,也就不会数组打散成若干个参数了. 

 

 

数组的反射:

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

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

       3.基本类型的一维数组可以代做Object类型使用,不能代做Object[]类型使用,非基本类型的一维数组,

       既可以当做Object类型使用,又可以当做Object[]类型使用.

 

Arrays.asList()方法处理int[] 和String[] 时的差异.

         String[]数组中的String对象都是Object对象,而int[]数组中的int,只是基本类型,不是一个Object对象.传递给asList()的实参,如果是String[]数组,那么,数组中的每个元都是Object对象。如果是int[]数组,数组中的元,都是一个基本 类型,不是Object。

          在JDK1.4中,传递给asList()方法的实参,是Object[]数组,

而在JDK1.5以及以上版本中,利用了可变参数来实现。当我们传递String[]数组给形参时,由于上述String[]的特性,即正确的传递了实参给asList()方法。

          但是,当我们传递给int[]数组给形参时,由于int[]数组的上述特性,错误的传递了形参,

那么,返回JDK1.5以上的版本,使之处理,而在该处理中,实参int[]将当做一个Object对象,即只能返回该对象的数组类型和散列码。

 

hashCode方法与HashSet类 

        如果想查找一个集合中是否包含有某个对象,大概的程序代码怎样写呢?当发现某个元素与要查找的对对象进行equals方法比较的结果相等时,则停止继续查找并返回肯定的信息,否则返回否定的信息。如果是一个集合中有很多元素,譬如有一万个元素,并且没有包含要查找的对象时,则意味着你的程序需要从该集合中取出一万个元素进行啄一的比较才能得到结论,有人发明了一种hashCode算法,来提高查找的效率,这种方式将集合分成若干个存储区域,每个对象可以计算出一个哈希码,可以将哈希码分组,每组分别对应某个存储区域,根据一个对象的哈希码就可以确定该对象应该存储在哪个区域,

 

 

         hashSet就是采用哈希算法存储对象的集合,它内部采用对某个数字n进行取余的方式对哈希码进行分组的划分对象的存储区域。Object中的hashCode用来返回对就java对象的哈希码,从而提高查找的效率。

 

         为了保证一个类的实例对象能在HashSet正常存储,要求这个类的两个实例对象用equals()方法比较的结果相等时,它们的哈希码也必须相等,也就是说,如果obj1.equals(obj2)的结果为true,那么一下表达式的结果页要为true。

 

obj1.hashCode() == obj2.hashCode()

 

         如果一个类的hashCode()方法没有遵循上述要求,那么,当这个的两个实例对象用equals()方法比较的结果相等时,它们本来应该无法同时存储进Set集合中,但是,如果将它们存储进HashSet集合中时,由于它们的hashCode()方法的返回值不同,第二个对象首先按哈希码计算可能会被放进与第一个对象不同的区域中,这样,它就不可能与第一个对象进行equals方法比较了,也就可能被存储进HashSet集合中了。Object类的hashCode()方法不能满足对象被存入到HashSet中的要求,因为它的返回值是通过对象的内存地址推算出来的,同一个对象在程序运行期间的任何时候返回的哈希值都是始终不变的,所以,只要是两个不同的实例对象,即使它们的equals方法比较结果相等,它们默认的hashCode方法的返回值是不同的。

提示:

 

(1)通常来说,一个类的两个实例对象用equals()方法比较的结果相等时,它们的哈希码也必须相等,但反之则不成立,即euqlas方法比较结果不相等的对象可以有相同的哈希码,或者说哈希码相同的两个对象的equals方法比较的结果可以不等,例如,字符串“BB”和"Aa"的euqals方法比较结果肯定不相等,但它们的hashCode方法返回值却相等。

 

(2)当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在cantains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果。这也会导致从HashSet集合中单独删除当前对象,从而造成内存泄露。

 

 

分享到:
评论

相关推荐

    黑马程序员_Java基础辅导班教程课件[第01期]第13天

    在"黑马程序员_Java基础辅导班教程课件[第01期]第13天"中,我们聚焦于Java编程语言的基础知识,这是一门面向初学者的课程,旨在帮助学员快速掌握Java开发的基本技能。第13天的课程通常会涵盖上一天(第12天)所学...

    01_黑马程序员_张孝祥_Java基础加强_课程价值与目标介绍.zip

    【标题】"01_黑马程序员_张孝祥_Java基础加强_课程价值与目标介绍.zip" 提供的是一门由黑马程序员机构推出的Java基础强化课程,由讲师张孝祥主讲,旨在深入讲解Java编程的基础知识并进行能力提升。 【描述】中提到...

    黑马程序员java基础试题、笔记

    "黑马程序员java基础试题、笔记"这个压缩包资源为Java初学者和希望加入"黑马程序员"培训课程的学员提供了丰富的学习材料。这些资源包括面试问题合集、整理的资料、Android面试题、学员入学面试总结、面试技巧、必须...

    黑马程序员入学Java知识——精华总结.doc

    以上只是Java知识体系的一部分,深入学习Java还需要掌握更多的概念和技术,如反射、注解、泛型、Lambda表达式、并发编程、Spring框架等。通过不断学习和实践,你可以成为一位出色的Java开发者。

    黑马程序员入学Java知识——精华总结

    含面向对象,异常处理和常用类,线程技术,集合框架,IO操作,网络编程,文件操作,反射机制,

    黑马程序员java面试宝典 完整版PDF.rar

    《黑马程序员Java面试宝典》是一本专门为Java开发者准备的面试指南,包含了广泛而深入的Java技术知识,以及面试过程中可能会遇到的各种问题。这本书的完整版PDF提供了丰富的学习材料,帮助求职者提升自己的技术水平...

    黑马程序员入学面试题

    3. **Java基础知识提问**:考察应聘者对于Java基础知识的掌握程度,包括但不限于数据类型、控制结构、面向对象特性等。 #### 2. 面向对象的理解 面向对象是一种编程范式,它将数据和处理这些数据的方法封装在一起...

    Java基础案例教程.rar

    本教程出自知名教育机构黑马程序员,该机构以其深入浅出的教学方式和实用的案例著称。 在本教程中,你将学习到以下关键知识点: 1. **Java环境搭建**:首先,你需要了解如何下载和安装Java Development Kit (JDK)...

    Java基础案例教程(第2版)_PPT.zip

    《Java基础案例教程(第2版)》是一本旨在教授初学者Java编程基础知识的教材,其PPT形式的压缩包提供了清晰、直观的教学材料。在深入探讨这些知识点之前,我们首先了解一下Java语言的基础概念。 Java是一种面向对象...

    黑马程序员《Java自学宝典》源代码

    Java自学宝典是针对初学者和有一定基础的学习者设计的一套完整的Java学习资源,由知名的教育机构黑马程序员出品。这份源代码压缩包包含了书中各个章节的实例代码,旨在帮助学习者深入理解Java编程语言的核心概念和...

    毕向东_Java基础视频源代码

    【毕向东_Java基础视频源代码】是一套由著名IT教育机构黑马程序员的资深讲师毕向东教授的Java编程基础课程的配套源代码。这套课程旨在帮助初学者掌握Java编程语言的核心概念和技术,为后续深入学习和开发打下坚实的...

    黑马程序员面试宝典(java)2018版

    《黑马程序员面试宝典(java)2018版》是一本专门为Java开发者准备的面试指南,涵盖了大量在面试过程中可能遇到的问题和知识点。这本宝典由黑马程序员机构精心编纂,汇集了近万名学员的实际面试经验,为求职者提供了...

    黑马java教程知识点笔记整理

    【Java编程基础】 ...以上是黑马Java教程知识点笔记的主要内容,涵盖了Java编程的基础到进阶知识,是学习和巩固Java技能的重要参考资料。通过深入理解和实践这些知识点,开发者可以逐步提升Java编程能力。

    2018-2019年黑马最新版Java程序员面试宝典+题库pdf

    《2018-2019年黑马最新版Java程序员面试宝典+题库pdf》是一份集合了近年来Java编程领域重点知识和面试常见问题的综合资源。这份资料主要针对初级Java程序员,旨在帮助他们巩固基础知识,掌握面试技巧,以便在求职...

    黑马程序员------类加载器学习注意点

    本文将主要围绕“黑马程序员------类加载器学习注意点”展开,探讨一些关键知识点。 首先,我们需要理解类加载器的基本工作原理。在Java中,类加载过程包括加载(Loading)、验证(Verification)、准备...

    Java基础案例教程(第2版)-课后习题答案.zip

    《Java基础案例教程(第2版)》是一本专为初学者设计的教材,旨在帮助学习者掌握Java语言的基础知识,并通过实践案例加深理解。本教程的课后习题答案包含在"Java基础案例教程(第2版)-课后习题答案.zip"压缩包中,...

    java.rar黑马java基础笔记

    《黑马程序员Java基础笔记》是一份全面覆盖Java编程基础知识的学习资料,旨在帮助初学者迅速掌握Java编程语言,能够独立编写Java程序。这份笔记由多个部分组成,分别详细讲解了Java的基础语法、集合、多线程、IO以及...

    黑马程序员:轻松精通Java学习路线基础篇!.docx

    以上只是Java 基础部分的核心知识点,随着深入学习,还会涉及网络编程、反射、注解、设计模式等多个方面。在学习过程中,结合实际项目练习,将理论知识应用于实践,将有助于更好地理解和掌握Java。

    黑马程序员----泛型与反射的小运用

    在Java编程语言中,泛型和反射是两个非常重要的特性,它们在软件开发中有着广泛的应用。本篇文章将深入探讨这两个概念以及它们在实际开发中的小运用。 首先,我们来看泛型(Generics)。泛型是在Java SE 5.0引入的...

Global site tag (gtag.js) - Google Analytics