学JAVA的第三天之反射

反射是什么? 是指在程序运行期间,可以动态创建对象。

(1)获得字节码文件对象的三种方法
为什么要获取字节码文件对象,只有这样,才能通过字节码文件对象去创建类的对象,而不是用new,这样方便了程序的修改。直接修改配置文件,便可以更改创建的类。
1.Object类的getclass()方法:同一个类的字节码只被加载一次
2.类.class:任何一个类在生成的.class文件中,会产生一个Class对象,用于表示这个类的类型信息
3.Class.forName(类名):注意类名的写法应该是全路径,包括包名

package demo;
public class test {
    public static void main(String[] args) throws ClassNotFoundException {
        //1.Object类的getclass()  通过同一个类创建的字节码文件是一样的,只被加载一次
        Person p1 = new Person();
        Person p2 = new Person();
        Class class1= p1.getClass();
        Class class2= p2.getClass();
        System.out.println(class1);
        System.out.println(class2);
        System.out.println(class1==class2);
        //2.类名.class对象
        Class class3= Person.class;
        System.out.println(class2==class3);
        //3.类型名.forName()
        Class class4= Class.forName("demo.Person");//注意是包名.类名
        System.out.println(class3==class4);
        //结果是:
        class demo.Person
		class demo.Person
		true
		true
		true

(2)字节码文件对象里面有什么

字节码文件对象
构造方法构造方法对象(类型为constructor)
成员变量成员变量对象(类型为filed)
成员函数成员函数对象(类型为method)

(3)用字节码文件对象来创建一个类的对象

------------------------------------------------Person2.java
package demo;
public class Person2 {
        public Person2(){};//类的构造方法1
        public Person2(String name,int age){//类的构造方法2
            super();
            this.name=name;
            this.age=age;
        }
        private String name;
        private int age;
        public void eat(){
            System.out.println("吃吃吃222");
        }
    }
------------------------------------------------test.java
package demo;
public class test {
    public static void  main(String[] args) {
      	 // Person p=new Person(); 这是传统的创建对象的方法
        //读取配置文件中类的信息,想创建什么类就创建什么,可在外部配置文件中修改
        FileReader f=new FileReader("aa.txt");
        BufferedReader br=new BufferedReader(f);
        String str=br.readLine();
        System.out.println(str);
        //--------------第一步:用Class.forName()来创建字节码文件对象
        Class clazz=Class.forName(str); 
        //--------------第二步:获取类中的构造器对象
        //获得Person类的构造方法,用Constructor数组来存储一共有几个(只能得到public的构造方法)
        Constructor[] constructors =clazz.getConstructors();
        System.out.println(constructors.length);
        System.out.println(constructors[0]);//输出构造方法1
        System.out.println(constructors[1]);//输出构造方法2
        //--------------第三步:选择其中一个,用newInstance()来创建对象
        Constructor c=constructors[0];
		//返回的是Object类型,再进行类型转换
        Object obj=c.newInstance();
        //相当于创建了一个Person2类的对象 a ,不是以前传统的用new创建的
        Person2 a=(Person2) obj;
        a.eat();
    }
}
//结果为:2
		public demo.Person2()
		public demo.Person2(java.lang.String,int)
		吃吃吃222

(4)得到字节码文件对象中的成员方法对象Method
1.获取字节码文件对象
2.得到某个特定的方法 【要知道方法名+形参】
3.创建对象【调用的传统方法是对象.方法(对象),但反射里面是:方法.invoke(对象,实参)】
4.反射调用

package demo;

public class Person2 {
    Person2(String name){//类的构造方法3
        super();
        this.name=name;
    }
    private String name;
    public void setName(String name) {
        this.name = name;
       System.out.println(name);
    }
}
package demo;

//-----------------------得到字节码中的成员方法对象 Method
public class test2 {
    public static void main(String[] args) {
  	    //--------------第一步:得到字节码文件对象
        Class clazz=Class.forName("demo.Person2");
        //Method[] methods= clazz.getMethods();//父类继承下来的+自身的+public,才可以显示出来
        //增强型的for循环。Method是元素类型,method是每一个元素变量,methods是你要遍历的数组
        //for(Method method:methods)
        //System.out.println(method);
         //--------------第二步:得到特定的方法 要知道方法名+形参。
        Method method=clazz.getMethod("setName",String.class);
        System.out.println(method);
        // Constructor constructor=clazz.getConstructor(); 传统方法是用构造器去创建实例
        //Object newInstance=constructor.newInstance();
        //--------------第三步:创建方法所在类的对象,是更便捷的方法,但只针对无参数
        Object newInstance=clazz.newInstance();
        //--------------第四步:反射调用
        Object a=method.invoke(newInstance,"haha");
    }
}
//结果是:public void demo.Person2.setName(java.lang.String)
haha

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值