黑马程序员——-Java反射机制-

                                                     黑马程序员——-Java反射机制-------
---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a 
href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! -------------------------------

反射机制:1.在程序编译时根本无法知道该对象或类可能属于哪些类,程序只依靠运行时信息来发现该对象和类的真实信息。
          2.对于任意一个对象,都能够调用它的任意一个属性和方法。
          3.反射技术可以对一个类进行解剖,大大提高程序的扩展性。
          3.通过动态获取类的信息,就是反射。例如人通过镜子对照自己的身体来打扮自己,知道自己的外貌情况。


反射实现基本步骤:
1.获取Class对象,既获取指定的名称的字节码文件对象。
2.实例化对象,获得类的属性、方法、构造函数。
3.访问属性,调用方法,调用构造函数创建对象。
         
一、反射获取class对象方法:
package com.itheima.reflect.demo;

import com.itheima.bean.Person;

public class ReflectDemo {

	/**
	 * @param hutian
	 * @throws ClassNotFoundException 
	 */
	/**
	 * @param args
	 * @throws ClassNotFoundException
	 */
	public static void main(String[] args) throws ClassNotFoundException {
		
		//getClassObject_3();
		getClassObject_2();
		//getClassObject_1();
	}
	/**
	 * 方式三:
	 * 1.通过给定的类、字符串名称就可以获取该类信息,更为扩展
	 * 2.用Class类中的方法完成,即Class。forName,要有名称即可反射,扩展性强
	 * @throws ClassNotFoundException 
	 */
	public static void getClassObject_3() throws ClassNotFoundException{
		
		String ClassName="com.itheima.bean.Person";
		Class clazz=Class.forName(ClassName); 
		System.out.print(clazz);
	}
	/**
	 * 方式二:
	 * 1.任何数据类型都具备一个静态属性 (。class)来获取对象的Class对象
	 * 2.必须先具备该类如 Person
	 * @throws ClassNotFoundException 
	 */
	
	public static void getClassObject_2() throws ClassNotFoundException{
		
		
		Class<Person> clazz=Person.class; 
		Class<Person> clazz1=Person.class; 
		System.out.println(clazz);
		System.out.print(clazz==clazz1); //true
		
	}
	/**
	 * 方式一:
	 * 1.获取字节码对象方式:
	 * 2.Object类中的getClass()方法  (通过上帝的getClass()方法获取)
	 * 2.用Class类中的方法完成,即forName,要有名称即可反射
	 * 前提:必须明确具体类,创建对象,比较麻烦 
	 */
	
	public static void getClassObject_1() throws ClassNotFoundException{
		
		
		Person p=new Person();
		 Class clazz=p.getClass();
		System.out.println(clazz);
		//System.out.print(clazz==clazz1); //true
		
	}
}


反射用法:
二:利用反射机制获取构造函数


package com.itheima.reflect.demo;


import java.lang.reflect.Constructor;


public class ReflectDemo2 {


/**
* @throws Exception 
* @胡田
* Constructor 类:代表某个类中的一个构造方法
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
CreateObject_2();
}


/**
* 通过指定构造函数对对象进行初始化
* 1.先获取该构造函数,通过字节码文件对象完成
* 方法:getConstructor(ParamterType);
*/
public static void CreateObject_2() throws Exception{

String ClassName="com.itheima.bean.Person";
//1.寻找该名称类文件,加载到内存,并产生Class对象
Class clazz=Class.forName(ClassName);

//2.获取指定构造函数对象
@SuppressWarnings("unchecked")
Constructor ct=clazz.getConstructor(String.class,int.class); //构造器指定函数对象

//3.通过构造器对象的newInstance方法对对象进行初始化
Object obj=ct.newInstance("小强",28);

}


}
总结: Constructor类构造方法反射主要步骤:
       1.获得构造方法:getConstructors() 或者 getConstructor 方法
       2.newInstance 方法 创建实例对象
//结果:这个人的姓名null年龄0  ,为什是null 有疑问,没反射获取到,初始化没有用


三:反射获取成员变量:
package com.itheima.reflect.demo;


import java.lang.reflect.Field;


public class ReflectDemo3 {


/**@胡田
* @param args
* @throws Exception 
*/
public static void main(String[] args) throws Exception {

getFileDemo();
}
//获取字节码中的成员
    public static void getFileDemo() throws  Exception{
   
    Class clazz=Class.forName("com.itheima.bean.Person");
    Field fl=null; //clazz.getField("age");  只能获取共有的,private私有属性不能获取
     
   
    fl=clazz.getDeclaredField("age"); //获取本类,包括私有的
    fl.setAccessible(true); //对私有成员强烈访问,称为暴力反射
   
Object obj=clazz.newInstance();  //初始化

fl.set(obj, 30);
Object o=fl.get(obj);

System.out.println(o);

    }
}
总结:Field 类代表某个类中的成员变量
//打印:人出生就会哭30


四:反射获取Class中公共函数
1.Class.forName //类名字符串获取信息
2.Method m  Class.getMethod //获取方法
3.Object obj


package com.itheima.reflect.demo;


import java.lang.reflect.Constructor;
import java.lang.reflect.Method;


public class ReflectDemo4 {


/**
*@throws Exception 
* @hutian
*/
//反射获取Class中的公共函数 ,getMethod
public static void main(String[] args) throws Exception {

//getMethodDemo3();
//getMethodDemo2();
getMethodDemo1();
}
    public static void getMethodDemo3() throws Exception{
    // 类名,字符串获取反射信息
    Class clazz=Class.forName("com.itheima.bean.Person");
     
    Method m=clazz.getMethod("paramMethod", String.class,int.class);  //获取方法
   
    Object obj=clazz.newInstance(); //对象初始化
    //invoke()表示调用的意思,需要传入对象和参数
    m.invoke("小强", 18);
    }
    
    public static void getMethodDemo2() throws Exception{
    // 类名,字符串获取反射信息
    Class clazz=Class.forName("com.itheima.bean.Person");
     
    Method m=clazz.getMethod("show",null);  //获取空参数一般方法
   
    //Object obj=clazz.newInstance(); //对象初始化
   
    Constructor ct=clazz.getConstructor(String.class,int.class);
   
    Object obj=ct.newInstance("小明",30);
   
    m.invoke(obj, null);
    }
    
    //获取指定Class类中的所有公共函数。。
    public static void getMethodDemo1() throws Exception{
    // 类名,字符串获取反射信息
    Class clazz=Class.forName("com.itheima.bean.Person");
     
    Method[] methods=clazz.getMethods();  //getMethods()获取的是共有的方法
            methods=clazz.getDeclaredMethods(); //获取本类中所有方法,包括私有。
        
    for(Method m:methods){
    System.out.println(m);
    }
   
    }
}


执行getMethodDemo1() 没问题




五、反射其他总结:
一、反射的基石--Class类
1、Java程序中的各个java类属于同一事物,描述这些类事物的java类名就是Class。
2、对比提问:从多的人用一个什么类表示?从多的java类用一个什么类表示?
    人类---Person
    java类--Class
    注意这里Class是大写的,不是关键字class。
3、对比提问:
    1)Person类代表人,它的实例对象就是张三,李四这样一个个具体的人,
    2)Class类代表java类,它的各个实现对象又分别对应什么呢?
对应各个类在内存中的字节码,例如Person类的字节码,ArrayList类的字节码,等待。
一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,
不同的类的字节码是不同的,所以它们在内存中的内容是不同的,这一个个的空间分别用一个个的对象来表示,这些对象显然具有相同的类型,这个类型是什么呢?
4、得到字节码对象的三种方法
    1)类名.class,例如System.class
    2)对象.getClass(),例如new Date().getClass()
    3)Class.forName("完整类名"),例如 Class.forName("java.util.Data");
  举例:
    Class clazz=Class.forName();
    Person p=new Person();
Class clazz=p.getClass(); //对象.getClass
    Method m=clazz.getMethod("参数方法");  //获取方法
 反射时主要用第三种。它是静态方法。
 面试题:Class.forName()的的作用是什么?
 获取一个类的字节码对象,如果该类的字节码已经在内存中存在,就可以直接调用,
 如果还没有存在,就调用类加载器进行加载,然后获取该类的字节码对象。
5、九个预定义的Class对象:
    
    八个基本类型和void,分别是:boolean、byte、char、short、int、long、float、double和void。
    int.class == Integer.TYPE
6、数组类型的Class实例对象用的方法是:
 Class.isArray()
7、总之,只要是在源程序中出现的类型,都有各自的Class实例对象,
    例如int[],void。


---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a 


href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! -------------------------------



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值