简单了解Class类

1. java反射机制概念

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。


2.Class类是整个反射操作的源头,而这个类的定义如下

   public  final class Class<T>    extends  Object  implements Serializable,GenericDeclaration Type,AnnotatedElemnet //反射的泛型几乎无用,使用的时候用“?“` 

但是如果想要使用Class类进行操作,那么就必须首先产生Class类的实例化对象,有如下三种方法:

  • Object类提供了一个返回Class类对象的方法:

  • 利用“类.class“取得,日后假的多的就是在Hibernate上:

  • 利用Class类的static方法取得:

public static Class<?> forName(String className)
                        throws ClassNotFoundException

如果是程序设计的人员,使用最多的方法一定是forName方法,但是如果是使用者,工厂设计模式最好利用反射机制解决耦合问题

3.利用反射实例化对象

Class类如果使用了forName方法之后,就可以使用Class类定义的newInstance()方法默认去调用类之中的无参构造方法进行操作: public T newInctance() throwa InstantiationException,IllegaAccessException,一定要记住,此泛型使用不到

4.实例: 新建Web项目

package demo;
class Student { 
      public Student (){
      System.out.println("Student类的toString()方法");
}

}

public class ReflectDemo{

public static void main(String[] args)   throws Exception{
/**
  *
  */
Class<?>cls=Class.forName("demo.Student");
Object obj=cls.newInstance();
System.out.println(obj);

}
}

//默认newInstance无参构造

5.操作构造方法
但是如果使用反射实例化类对象,必须要求类中存在无参构造方法,因为默认使用Class类的newInstance(),能够找到无参,这个时候只能取得类之中的构造方法,传递所需要的参数后才可执行

在Class类里面定义了能够取得一个类之中构造方法的操作:
取得类之中的全部构造:

 public Constructor<?>[] getConstructors()
                                 throws SecurityException

取得勒种指定参数的构造:

public Constructor<T> getConstructor(Class<?>... parameterTypes)throws NoSuchMethodException,SecurityException

6.范例:String类型的所有构造方法

package demo;

import java.lang.reflect.Constructor;

public class ReflectStringDemo {
public static void main(String[] args) throws ClassNotFoundException {
    /*返回String的所有构造方法*/
    Class<?> cls=Class.forName("java.lang.String");
    Constructor<?>[]cons=cls.getConstructors();
    for (int i = 0; i < cons.length; i++) {
        System.out.println(cons[i]);
    }
}
}

所以如果现在想要进行指定构造方法的使用,就不需把关注点放在Constructor类之中,再次类中定义了一个实例化对象的方法:

public T newInstance()
              throws InstantiationException,
                     IllegalAccessException

获得构造方法:

public Constructor<T> getConstructor(Class<?>... parameterTypes)
                              throws NoSuchMethodException,
                                     SecurityException
//范例:Student:
package demo;

import java.lang.reflect.Constructor;

class Student1 { 
    private  String name;
    private Integer age;
    public   Student1(String name,Integer age){
        this.name=name;
        this.age=age;
    }
    public String toString(){
        return "姓名:" + this.name+ ",年龄:" + this.age.toString() ;
    }
    }




public class ReflectDemo1{

public static void main(String[] args)   throws Exception{
Class<?>cls=Class.forName("demo.Student1");
Constructor<?>cons=cls.getConstructor(String.class,Integer.class);
Object obj=cons.newInstance("what?",20);
System.out.println(obj);

}


}

7.调用类中方法
实际上由两类:
取得父类继承而来的方法:
取得父类全部方法:

public Method[] getMethods()
                    throws SecurityException
        去的父类的指定方法:
public Method getMethod(String name,
                    Class<?>... parameterTypes)
                    throws NoSuchMethodException,
                        SecurityException
  取得本类继承而来的方法:
       取得本类全部方法:
public Method[] getDeclaredMethods()
                            throws SecurityException
        去的本类的指定方法:
public Method getDeclaredMethod(String name,
                       Class<?>... parameterTypes)
                         throws NoSuchMethodException,
                                SecurityException

但是以上的操作在方法定义上区别不大,因为方法大部分是public

范例:返回父类,本类方法


package demo;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
interface Message {
    public void  get() ;
};
class Student2  implements
  Message{ 
    public void  print(){}
    private void siyou(){}
    public void fun(){}
    @Override
    public void get() {}
    }




public class ReflectDemo2{

public static void main(String[] args)   throws Exception{
Class<?>cls=Class.forName("demo.Student2");
Method  []met=cls.getMethods();
/*Method  []met=cls.getDeclaredMethods();*/
for (int i = 0; i < met.length; i++) {
    System.out.println(met[i]);
}

}


}

实例输出:方法名

package demo;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
interface Message {
    public void  get() ;
};
class Student2  implements
  Message{ 
    public void  print(){}
    private void siyou(){}
    public void fun(){}
    @Override
    public void get() {}
    }




public class ReflectDemo2{
    /*返回父类中,本类中所有构造方法*/
public static void main(String[] args)   throws Exception{
Class<?>cls=Class.forName("demo.Student2");
Method  []met=cls.getMethods();
/*Method  []met=cls.getDeclaredMethods();*/
for (int i = 0; i < met.length; i++) {
    //System.out.println(met[i]);
    System.out.print(Modifier.toString(met[i].getModifiers())+ "  ");
    System.out.print(met[i].getReturnType().getSimpleName()+"  ");
    System.out.print (met[i].getName()+"(  ");
    if(i<met.length){
        System.out.println(")");
    }
    System.out.println();

}

}


}

此类代码一般在编写开发工具的时候出现,而所谓的随笔提示功能即使依据以代码方式实现的,但是与开发者密切关联是紧密的一定是利用Method调用类中的方法,而且在Method类里面提供有一个重要方法:

//调用:
public Object invoke(Object obj,
            Object... args)
              throws IllegalAccessException,
                     IllegalArgumentException,
                     InvocationTargetException

实例

package demo;

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

class Student3 {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}


public class ReflectDemo3{

public static void main(String[] args)   throws Exception{
Class<?>cls=Class.forName("demo.Student3");
Object obj=cls.newInstance();//实例化对象
Method  setNameMethod=cls.getMethod("setName",String.class);
Method  getNameMethod=cls.getMethod("getName");
setNameMethod.invoke(obj,"mike");
System.out.println(getNameMethod.invoke(obj));

}

}

正以为如此,所以开发中才强调有setter,getter必须按照严格要求
8.调用类中的属性(尽量不要用)
关于类之中的属性也可以直接利用反射进行操作,而支持的方法有两类:
取得所有继承而来的属性:
取得全部属性:public Field[] getFields() throws SecurityException
取得指定属性:public Field getField(String name)throws NoSuchFieldException,SecurityException // 取得本类定义的属性
取得全部属性:
public Field[] getFields() throws SecurityExcepytion

          取得指定属性:              
  public Field getField(String name)throws NoSuchFieldException,SecurityException

9.在Construtor,Method,Field 三个类中有一个共同的父类AccessibleObject,这个类里定义了可以取消封装的方法如下:

public static void setAccessible(AccessibleObject[] array, boolean flag)throws SecurityException

猜你喜欢

转载自blog.csdn.net/MYCSDN6666/article/details/80706336