黑马程序员-类加载机制和反射

 

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

  • Class的由来(用于表述字节码文件的类的名称就是Class)

当程序主动使用一个类时。如果该类还未加载到内存当中。则系统会通过加载,链接,初始化3个步骤来对类进行初始化,如果没有意外,JVM将会联系完成这个步骤。

而类的加载就是将类的class文件读入内存当中,并为此创建一个java.lang.Class对象,那么我们可以理解,我们在程序当中使用任何一个类时,系统都会为此创建一个java.lang.Class对象。 

可以理解的就是:我们如果获取到字节码对象,就可以操作字节码对象当中的内容,这样我们不久可以动态的获取类中的内容并且使用了。

 摘录:我们知道。类是一类对象的抽象,那么我们可以这样想一下,类也是一种对象,而类是一种概念层次的东西,我们说描述主要用于定义和描述其他事物,但是概念本身也需要一些描述,也就是说需要另外一个类来描述这些类的抽象,那么我们的Class类就产生了。

  • JAVA程序中的类属于同一个事物,描述这类事物的类就叫Class

一个类被加载到内存当中,占用一片存储空间,这个空间里面的内容就该类字节码,不同的类的字节码是不同的,所以他们在内存中的内容也是不相同的,这一个个空间可以分别咏鹅一个个对象来表示,这些对象。

但是我们可以总结出,这些对象也会有相同的类型,这个类型就是Class类

 

  • 基本的 Java 类型(booleanbytecharshortintlongfloatdouble)和关键字 void 也表示为 Class 对象。
  • Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。

 

  • 那么我们如何获得类的Class对象呢?(就是如何获取字节码对象)可以理解这是反射的核心。

我们用一段代码来演示

		//获取到字节码的3种方法
		String str = "zhulang";
		
		/*
		 * 方式一
		 * 使用Object类当中的getClass方法。
		 * 但是这个方法必须要创建未知类对象,在调用getClass方法
		 */
		Class class1 = str.getClass();
		
		/**
		 * 方式二
		 * 使用该类的静态class属性获取。这个方式和一一样,还是要知道未知的类。
		 */
		Class class2 = String.class;
		
		/**
		 * 方式三。
		 * 通过Class类当中的静态方法 forName(String className)来完成。
		 * 该方法根基传入类的名称,自动去classPath路径下去寻找改名称相同的类文件
		 * 然后通过类加载器进行加载,并且在内存当中生成类的字节码文件对象。
		 */
		Class class3 = Class.forName("java.lang.String");
		
		System.out.println(class1 == class2);
		System.out.println(class1 == class3);

  

结果是

 


 

反射

反射:就是把java类中个成份映射一个Java类,包括Class,Method,Field,Constructorh和Array等等,这些类分别代表类,方法,Field,构造器和数组。

反射的由来

1.在不明确日后出现什么样的实现类是,可以扩展出去,对外提供配置文件,让后期的实现类都定义在配置文件中,

2.该程序会读取配置文件并根据指定的名字寻找对应的类。

3.找到对应的类进行对象的建立,

4.并且调用该类对象的成员,

可以说反射大大提高程序的扩展性。

 


  • 反射字段
private void fieldDemo() throws Exception
	{
		/*
		 * 获取获取指定类当中的指定名称的字段
		 * 思路:先要获取到该类的字节码文件对象
		 * 2.通过字节码文件对象 获取当中的成员字段
		 * 	
		 */	
		String className ="com.text.Person";
		
		//获取到 该类的字节码文件对象
		Class perClass = Class.forName(className);
		//获取到成员字段的对象
		Field field = perClass.getDeclaredField("age");
		//获取到,那么我们要进行字段的设置一个值,要想设置值,那么我们得实列化一个成员对象。
		Object obj = perClass.newInstance();
		field.setAccessible(true);
		//对象也创建了,那么我们怎么给字段设置值呢?
		field.set(obj, 18);	
		//我们现在来获取方法来设置字段的值	
		//我们来操作方法了。
		System.out.println(field.get(obj));

	}
  • 反射构造函数演示
    /**
    	 * 反射构造函数
    	 */
        private static void  constructorDemo() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException 
    	{
    		//反射构造函数有什么作用。有构造函数我们就能够对构造函数进行初始化
        	
        	String className = "com.text.Person";
        	
        	//获得Class对象   我的理解是理解是里面包含 类里面成员映射的许多对象
        	Class percls = Class.forName(className);
        	
        	//获取Person类的构造函数的对象
        	Constructor con = percls.getConstructor(String.class);
        	Person obj  =(Person) con.newInstance("zhulang");
        	System.out.println(obj.getName());
        	
    	 
  • 反射方法
     /**
         * 反射方法。
         */
        private static void MethodDemo() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException 
    	{
    		//获取到Class集合
        	Class metClass = Class.forName("com.text.Person");
        	
        	//那么我们要获取到方法类。 
        	Method met= metClass.getMethod("show", null);
        	
        	//获取指定的对象
        	Object obj = metClass.newInstance();
        	//通过该该对象调用该方法。
        	met.invoke(obj,null);
        	
        	/*
        	 * 上面两行代码等同于
        	 * Person per = new Person();
        	 * per.show();
        	 */
    	}
    

      

  • 上面用到的类Person
public class Person
{
	private String name;
	private int age ; 
	public Person()
	{
		
	}
	
	public  Person(String str)
	{
		this.name =str;
		
	}
	public String getName()
	{
		return name;
	}
	public void setName(String name)
	{
		this.name = name;
	}
	public void show()
	{
		System.out.println("Person Show run");
	}
}

  

    

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值