反射机制(初识+笔记)——混乱

目的是在运行时可以加载到之前没有加载到jvm的。
正常使用类的步骤:

  1. 使用import导入类所在的包(java.lang.Class)
  2. 明确的使用类明程或者接口明程定义对象
  3. 通过关键字new进行类对象实例化(构造方法:java.lang reflect.Constructor)
  4. 产生对象可以使用“对象.属性”进行类中属性的调用(java.lang.reflect.Field)
  5. 通过“对象.方法()”调用类中方法(java.lang.reflect.Method)
    附:反射的泛型几乎无用,使用的时候用“?”

附:如果想要使用Class类进行操作,那么就必须首先产生Class类的实例化对象

  1. Object类提供了一个返回Class类对象的方法:public Class<?> getClass()
  2. 利用类.class取得,日后见得最多的就是在Hibernate
  3. 利用Class类的static方法取得;public static Class<?> forName(String className) throws ClassNotFoundException

工厂设计模式最好利用反射机制解决耦合问题。

请解释Object类之中的所有方法以及每一个方法使用上的注意事项:

  1. 对象克隆:public Object clone() throws CloneNotSupportedException;
    克隆对象所在的类一定要实现java.lang.Cloneable接口,而且子类只需要继续调用Object类的clone()方法就可以实现克隆操作。
  2. 对象输出 public String toString();
  3. 对象比较:public boolean equals(Object obj),当保存set集合时,会依靠hashCode()和equals()判断是否为重复对象
  4. 取得对象的hash码,public in hashCode();可以理解为每一个类对象的唯一编码,比较时会先判断编码是否相同,后比较内容
  5. 取得Class类对象,public Class<?> getClass();通过一个已经实例化好的对象进行对象的反射操作。
  6. 线程等待:public void wait() InterceptorException;执行到此代码时线程要等待执行,一直到执行notify()、notifyAll()。唤醒第一个等待线程public void notify(),唤醒全部等待线程public void notifyAll()。
Class<?> cls = Class.forName(".....Student");
//以下代码相当于用关键字new实例化对象,相当于Object obj = new Student();
Object obj = cls.newInstance();

上面的例子中可以看出,可以不通过new直接进行实例化操作。但是如果使用反射实例化类对象,必须要求类中存在有无参构造方法,只能够找到无参构造方法。此时需要取得类中的构造方法,传递所需要的参数后才可以执行
取得类中的全部构造 public Constructor<?>[]
取得类中指定参数的构造 public Constructor
例子:取得String类的全部构造方法
Class<?> cls = Class.forName(“java.lang.String”);
Constructor<?> [] cons = cls.getConstructors(); 取得全部构造
即可输出。
如果想要进行指定构造方法的调用,就必须将关注点放在Constructor类型中。
看Constructor类。在此类中定义了一个实例化对象方法public T newInstance(Object… initargs) throws…

若是带参构造方法,则
Class<?> cls = Class.forName("…Student")
Constructor<?> cons = cls.getConstructor(String.class, Integer.class)
Object obj = cons.newInstance(“lisi”, 20);

和上面的无参构造进行比较

正式因为如果是通过构造方法实例化对象规格不统一。所以在进行简单Java操作时明确规定必须有无参构造方法。

调用类中的方法

类中的方法有两类,一个是从父类继承,一个是本类定义的。

  1. 取得父类继承而来的方法:

取得全部方法:
public Method[] getMethods() throws SecurityException
取得指定方法:
public Method getMethod(String name, Class<?>…parameterTypes) throws NoSuchMethodException, SecurityException;

  1. 取得本类定义的方法:
    取得全部(公有?)方法:public Method[] getDeclaredMethods() throws SecurityException

取得指定方法:public Method getDeclaredMethod(String name, Class<?>… parameterTypes) throws NoSuchMethodException, SecurityException

Class<?> cls = Class.forName("....Student");
Method met[] = cls.getMethods();

现在的程序是直接调用了Method类中的toString()方法实现的输出,如果用户有需要也可以自己去整理方法的输出,可以使用到Method类的如下方法:

  1. 取得方法修饰符。 public int getModifiers();
    该方法得到的是一串数字,因为在程序中找的不是public、static等关键字,而是关键字所代表的数字,如果要换成我们一眼能懂的信息,可以借助Modifier类完成,此类中可以直接利用方法取得将数字变为修饰符。
public static String toString(int mod)//
Modifier.toString(met[x].getModifiers)

取得方法的返回参数类型public Class<?> getReturnType();

met[x].getReturnType()//返回连带着包
met[x].getReturnType().getSimpleName()//返回的不带包名

取得方法的参数public Class<?> [] getParameterTypes();

Class<?> params[] = met[x].getParameterTypes();//获得的是全部参数

调用类中的属性(尽量不要使用)

关于类中的属性也可以直接利用反射进行操作,而支持的方法有两类:
取得所有继承而来的属性

  1. 取得全部属性
    public Field[] getFields() throws SecurityException
  2. 取得指定属性
    public Field getField(String name) throws NoSuchMethodException, SecurityException
    取得本类定义的属性

1.取得全部属性
public Field[] getDeclareFields() throws SecurityException
2.取得指定属性
public Field getDeclareField(String name) throws NoSuchMethodException, SecurityException

Class<?> cls = Class.forName(".....Student");
Field fields [] = cls.getFields();//继承而来的全部属性
                = cls.getDeclareFields()//本类定义的属性
cls.getSuperclass().getDeclaredField;//取得父类属性

在Field类里面还定义有进行属性调用的方法

  1. 设置属性内容
    public void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException
  2. 取得属性内容
    public Object get(Object obj) throws IllegalArgumentException, IllegalAccessException
    在Constructor、Method、Field三个类上有一个共同的父类AccessibleObject,在这个类里面定义了可以取消封装的操作方法(如果不取消有异常)
Class<?> cls = Class.forName("....Student);
Object obj = cls.newInstance();
Field schoolField = cls.getDeclaredField("school");
schoolField.setAccessible(true)//取消封装
schoolField.set(obj,"大学");

web对反射的操作支持

在jsp中有一种技术——JavaBean,而且在jsp里面也配套有相应的操作方式。JavaBean核心在于简单Java类。

package vo;
import java.io.Serializable;
@SuppressWarnings("serial")
public class Student implements Serializable{
private String name;
private Integer age;
private Double score;
}
此时有三种数据类型,并且要求完成setter和getter,在web项目中所建立的每一个*.java类最终会保存在WEB-INF/classes中,所以classes就是一个CLASSPATH。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值