Java--反射

1.反射是什么?(W)

反射是运行中的程序检查自己和软件运行环境的能力,它可以根据它发现的进行改变。反射可以在运行时根据指定的类名获得类的信息。(无需使用new 就能实例化对象)

2.为什么要有反射?(W)

利用反射,可以实现更好的解耦合操作。(代替new来实现对象实例化操作)

3.Object类中的getClass()方法:

作用:通过对象取得此对象所在类的信息。
当我们使用getClass方法时,返回的类型为java.lang.class,这是反射操作的源头类,即所有的反射操作都需要通过此类开始。

4.java.lang.Class类对象实例化:

有如下三种方法:

I.调用Object类中的getClass()方法,此类操作必须有实例化对象。

import java.util.Date;
public class Demo {
    public static void main(String[] args) {
        Date date = new Date();
        Class<?> cls = date.getClass();
        System.out.println(cls.getName());
    }
}
java.util.Date

II.使用"类.class"取得,此时可以不用通过指定类的实例化对象取得

public class Demo {
    public static void main(String[] args) {
    	Class<?> cls =java.lang.Object.class;
        System.out.println(cls.getName());
    }
}
java.lang.Object

III.调用Class类提供的方法:

public static<?> forName(String className)throws ClassNotFoundException
public class Demo {
    public static void main(String[] args)throws Exception {
        Class<?> cls =Class.forName("java.lang.Object");
        System.out.println(cls.getName());
    }
}
java.lang.Object

III中调用了Class类中forname()方法。

5.反射怎么用?(H)

掌握了Class类对象实例化的三种操作形式,就可以利用Class类来进行类的反射控制了。
Class类中有如下重要方法:

public T newInstance()
              throws InstantiationException,
                     IllegalAccessException

public static<?> forName(String name,
                               boolean initialize,
                               ClassLoader loader)
                        throws ClassNotFoundException

最重要的就是newInstance()方法,作用是反射实例化对象。(不使用new也可以生成对象),此方法返回的类型为Object。
如果要使用此方法反射实例化对象,则类中一定要提供无参构造方法

利用反射实例化对象:

class Book {
    public Book() {
        System.out.println("*****这是无参构造");
    }
    @Override
    public String toString() {
        return "《*****》";
    }
}
public class Demo {
    public static void main(String[] args)throws Exception {
        Class<?> cls =Class.forName("Book");   //设置要操作对象的类名称
        // 反射实例化后的对象返回的结果都是Object类型
        Object obj = cls.newInstance();            //相当于使用new调用无参构造
        Book book = (Book) obj;                    //向下转型
        System.out.println(book);
    }
}
*****这是无参构造
《*****

6.使用反射调用构造:

利用Class类的newInstance()方法可以实现反射实例化对象的操作,但是类中必须提供有无参构造方法。如果类中只提供有参构造方法时,就必须通过java.lang.reflect.Constructor类来实现对象的反射实例化操作。
另外,java.lang.reflect是所有反射操作类的程序包,类中的每一个结构都有相应的类进行操作定义,如:构造方法会使用Constructor类。

java.lang.Class类中取得类中的构造方法:

public Constructor<?>[] getConstructors()
//取得全部构造方法               throws SecurityException
public Constructor<T> getConstructor(<?>... parameterTypes)
//取得指定参数类型的构造方法       throws NoSuchMethodException,
                                     SecurityException

利用以上两个方法可以取得java.lang.reflect.Construcor,而Constructor类的最重要的方法如下:
调用指定参数的构造实例化类对象

public T newInstance(Object... initargs)
              throws InstantiationException,
                     IllegalAccessException,
                     IllegalArgumentException,
                     InvocationTargetException

明确调用类中的有参构造方法:

import java.lang.reflect.Constructor;
class Book {
    private String name;
    private double price;
    public Book(String name,double price){
        this.name=name;
        this.price=price;
    }
    @Override
    public String toString() {
        return "图书名"+name +",价格"+price ;
    }
}
public class Demo {
    public static void main(String[] args)throws Exception {
        Class<?> cls =Class.forName("Book");   //设置要操作对象的类名称
        //找到Book类中两个参数的构造
        Constructor<?> cst =cls.getConstructor(String.class,double.class);
        Object obj =cst.newInstance("Java开发",66.6);         //实例化对象,传递内容
        System.out.println(obj);
    }
}

以上程序首先利用Class类取得此构造方法,返回Constructor对象,然后利用Constructor类的newInstance()方法传递指定数据,就完成了对象的反射实例化。

7.反射调用方法:

java.lang.Class类取得普通方法的操作:

public 方法[] getMethods()
//取得类中的全部方法  throws SecurityException
public 方法 getMethod(String name,
//取得类中指定方法名称与参数类型的方法                        类<?>... parameterTypes)
   throws NoSuchMethodException,
                        SecurityException

java.lang.reflect.Method类的最重要方法:

public Object invoke(Object obj,
                     Object... args)
              throws IllegalAccessException,
                     IllegalArgumentException,
                     InvocationTargetException

8.反射调用成员:

java.lang.Class类中取得成员的操作:

//取得本类继承父类的全部成员
public Field[] getFields()
                  throws SecurityException
                  
//取得本类继承父类中指定名称的成员
public Field getField(String name)
               throws NoSuchFieldException,
                      SecurityException
                      
//取得本类定义的全部成员
public Field[] getDeclaredFields()
                          throws SecurityException

//取得本类指定名称的成员
public Field getDeclaredField(String name)
                       throws NoSuchFieldException,
                              SecurityException

java.lang.reflect.Field类常用方法:

//取得该成员的类型
public<?> getType()

//取得指定对象成员中的内容,相当于直接调用成员
public Object get(Object obj)
           throws IllegalArgumentException,
                  IllegalAccessException
//设置指定对象成员中的内容,相当于直接调用成员设置内容
public void set(Object obj,
                Object value)
         throws IllegalArgumentException,
                IllegalAccessException

利用反射直接操作私有成员:

import java.lang.reflect.Field;
class Book {
    private String name;
}
public class Demo {
    public static void main(String[] args)throws Exception {
        Class<?> cls =Class.forName("Book");   //取得反射对象
        Object obj =cls.newInstance();         //实例化对象
        Field titleField =cls.getDeclaredField("title");//取得类中的title属性
        titleField.setAccessible(true);         //取消封装
        titleField.set(obj,"第一行代码------");
        System.out.println(titleField.get(obj));
    }
}

titleField.setAccessible(true);作用就是取消封装,如果没有特殊需要尽量不适用这种。所有属性访问还是要通过setter、getter方法操作。

无论是使用反射调用普通还是方法类中的成员,都必须存在实例化对象,因为类中的属性必须在类产生实例化对象(有堆内存空间)后才可以正常使用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值