枚举类型与Java反射编程机制

f# Java枚举类型

枚举类型概述

  • Java中枚举类型属于自定义引用类型,定义枚举类型使用enum关键字修饰类
  • 枚举类型通常包含一组常量数据值适合某种事物固定的构成结构(如季节由 ‘春夏秋冬’ 四季组成)
  • 枚举类型可以实现某个接口,但是枚举类型不能继承其他类同时枚举类型也不能被其他类所继承
  • 枚举类型可以定义非抽象方法,方法必需在所有枚举常量之后;枚举类型中也可以定义内部类及内部接口

枚举类型的定义

public enum SignalLamp {
	/*枚举常量定义*/
	RED,//常量之间用逗号分隔
	GREEN,
	YELLOW;
	//只能定义一组常量
}

枚举常用实例方法

  • public final int compare To(E o):比较枚举值索引大小,返回差值
  • public final String name():获取枚举名称的字符串形式
  • public final int ordinal():获取枚举所在枚举集合中位置的索引
  • public static E[] values():获取所有枚举数组形式
  • public static valueOf(String name):根据参数获取枚举常量对象
/***
 * @date 2020/8/18
 * @author Vbird
 *  */
public class EunmTest {

	public static void main(String []args) {
		
		/*遍历枚举值与索引*/
		SignalLamp[] sigalLamp = SignalLamp.values();
		for(SignalLamp s:sigalLamp) {
			System.out.println("枚举索引"+s.ordinal());
			System.out.println("枚举名称"+s);
		}
		/*比较大小*/
		System.out.println(SignalLamp.RED.compareTo(SignalLamp.YELLOW));//输出为-2
		/*根据字符串获取枚举对象*/
		SignalLamp.valueOf("RED");
	}
}

反射编程

反射编程概述

  • Java中的反射编程时通过JVM运行时获取某个类型的字节码(Class)对象,从而利用其反向获取此类型定义的内部信息实现编程的一种机制
  • 反射编程通常属于非常规操作,存在一定的问题
  • 反射编程在设计开发工具框架时使用较多,诸如spring,hibernate等Java应用框架技术中使用比较频繁
  • 反射编程比较普通的编程方式执行效率相对要低

反射编程常用组件

  • java.lang.Class:字节码类型
  • java.lang.reflect.Constructor:构造器类型
  • java.lang.reflect.Method:方法类型
  • java.lang.reflect.Field:属性类型
  • java.lang.reflect.Modifier:访问修饰符类型

Class类

Class类概述

Class类的实例表示正在运行的Java应用程序中的类和接口,是字节码的实例Class没有公共构造方法。Class对象是在加载类时由Java虚拟机以及通过调用类加载器中的defineClass方法自动构造的。任何一个java对象都可以获得一个和其相关的Class对象。利用Class对象可以获得此类信息;所有同一类型的实例共享一个字节码对象

Class类常用方法

  • public static Class<?> forName(String className):获取某个类的字节码对象,className为某个类的绝对路径的包名
  • public T newInstance():根据字节码对象获取实例对象
  • public Field getField(String name):根据字段名name获取当前类所定义的公有(public)字段(属性)
  • public Field[] getFields():获取当前类的所有公有(public)字段
  • public Field getDeclaredField(String name):根据字段名name获取任何字段
  • public Method getMethod(String name,Class<?>…parameterTypes):根据方法名称name获取当前类的某一公有方法(…+类型 表示动态数组,只能用在参数中,parameter Types表示方法的参数类型,用于区别重载方法
  • public Method getMethods():获取当前类所有的公有方法
  • public Constructor getConstructor(Class<?>…parameterTypes):获取当前类的构造器
  • public Constructor<?>[] getConstructors():获取当前类所有构造器
  • public native int getModifiers():获取当前类的访问标识符
  • public ClassLoader getClassLoader():获取类加载器
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/***
 * @date 2020/8/18
 * @author Vbird
 * DESC 使用Class实现反射编程,创建对象,获取类的相关信息
 */
public class ClassTest {

	public static void main(String []args) {
		
		
		try {
			/*使用Class获取字节码对象*/
			Class<?> stuObj = Class.forName("day.twenty.four.Student");
			/*使用字节码对象获取实例对象*/
			Student stuClass = (Student)stuObj.newInstance();//默认访问无参构造器构造该对象,没有无参构造器时抛出异常
			/*获取公有字段(成员属性)*/
			Field field = stuObj.getField("name");//当参数不是公有字段或不存在时抛出异常
			Field[] fields = stuObj.getFields();//获取所有公共字段
			/*获取所有字段*/
			Field field2 = stuObj.getDeclaredField("age");
			Field[] fields2 = stuObj.getDeclaredFields();
			/*获取构造器*/
			Constructor<?> con = stuObj.getConstructor(String.class,int.class);//根据参数类型获取指定构造器
			Constructor[] cons = stuObj.getConstructors();//获取所有构造器
			/*获取公有方法*/
			Method method = stuObj.getMethod("getClass",null);//可以获取父类的方法
			Method[] methods = stuObj.getMethods();//获取所有方法,包括父类的方法,所以每一个类都会包含Object类的方法
			/*获取访问级别*/;
			System.out.println(stuObj.getModifiers()==Modifier.PUBLIC);
			
		} catch (Exception e) {//使用超级父类Exception涵盖了所有编译型异常
			e.printStackTrace();
		}
	}
}

Constructor类

Constructor类概述

  • Constructor类表示某个类的构造方法实例类型利用Constructor可以创建Constructor所在类的实例并对此类进行初始化等操作
  • Constructor没有公有的构造方法,所以不能实例化它,可以通过某个类的Class实例获得一个Constructor实例

Constructor类常用方法

  • public T newInstance(Object…initargs):根据Constructor类型获取实例对象,参数及构造器的参数
  • public void setAccessible(boolean flag):设置可访问性,动态改变,不会变动原来的级别
  • public int getModifiers():获取访问级别
  • pulblic Parameter[] getParameters():获取所有参数
  • public int getParameterCount():获取参数的个数
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;

/***
 * @date 2020/8/18
 * @author Vbird
 */
public class ConstructorTest {

	public static void main(String []args) {
		
		try {
			/*获取字节码对象*/
			Class<?> stuObj = Class.forName("day.twenty.four.Student");
			/*获取构造器对象*/
			Constructor con = stuObj.getConstructor(String.class,int.class);
			/*根据构造器获取实例对象*/
			Student stu = (Student)con.newInstance("张三",32);
			/*获取访问级别*/
			System.out.println(con.getModifiers()==Modifier.PUBLIC);//判断访问级别是否为pulbic
			/*获取参数信息*/
			Parameter[] param = con.getParameters();//获取所有参数
			int count = con.getParameterCount();//获取参数个数
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Field类

Field类概述

  • Field提供有关类或接口的单个字段信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段
  • Field提供了对字段的反射操作动作,使编程中访问属性字段更加灵活

Field类常用方法

  • public void set(Object obj, Object value):为字段赋值,第一个参数表示字段所属的实例对象,第二个参数表示赋予的值
  • public Object get(Object obj):获取字段值
  • public void setAccessible(boolean flag):设置可访问性,动态改变,不会变动原来的级别
  • public int getModifiers():获取访问级别
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/***
 * @date 2020/8/18
 * @author Vbird
 */
public class FieldTest {

	public static void main(String []args) {
		
		try {
			/*获取字节码对象*/
			Class<?> stuObj = Class.forName("day.twenty.four.Student");
			/*获取实例对象*/
			Student stu = (Student) stuObj.newInstance();
			/*获取某个成员字段*/
			Field field = stuObj.getField("name");//获取公共级别字段
			Field field2 = stuObj.getDeclaredField("sex");//获取任意级别的字段
			/*为字段赋值*/
			field.set(stu, "张三");//第一个参数应该为实例对象而不是字节码对象
			/* sex字段是私有级别,不可访问
			 * 此方法在这一个线程中(此main方法中)将sex访问级别设为公有,并不改变原有的级别
			 */
			if(field2.getModifiers()==Modifier.PRIVATE) {
				field2.setAccessible(true);
				field2.set(stu, "男");
			}
			/*获取字段值*/
			field.get(stu);
			field2.get(stu);
			/*获取字段访问级别*/
			System.out.println(field2.getModifiers()==Modifier.PUBLIC);//判断字段级别是否是public
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Method类

获得Method对象

  • Method getMethod(String name,Class… parameterTypes):根据方法名和参数类型获得公共方法

  • Method[] getMethod();获得所有的公共方法

  • Method getDeclaredMethod(String
    name,Class…parameterTypes);根据方法名和参数类型获得方法(可以为非公共方法

  • Method[] getDeclaredMethods();获得当前类中的所有方法。

Method常用方法

  • String getName();获得方法名。
  • int getModifiers();获得修饰符。
  • Class getReturnTypes();获得返回值类型。
  • Class[] getParameterTypes();获得参数类型的数组。
  • Objec invoke(Object obj,Object…args):执行方法,第一个参数为执行该方法的对象,第二个参数为执行方法时传入的参数

利用反射查看String类里面有多少个公开的构造器 属性和方法,有多少个私有的构造器 属性和方法

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

/***
 * @date 2020/8/18
 * @author Vbird
 * DESC 利用反射查看String类里面有多少个公开的构造器 属性和方法,有多少个私有的构造器 属性和方法。
 */
public class Work {

	public static void main(String []args) {
		
		int pubConsCount = 0;//公有构造器数量
		int pubFieldCount = 0;//公有属性数量
		int pubMethodCount = 0;//公有方法数量
		int priConsCount = 0;//私有构造器数量
		int priFieldCount = 0;//私有属性数量
		int priMethodCount = 0;//私有方法数量
		try {
			/*创建字节码对象*/
			Class<?> strObj = Class.forName("java.lang.String");
			/*创建实例对象*/
			String str = (String)strObj.newInstance();
			/*获取构造器信息*/
			Constructor[] cons = strObj.getDeclaredConstructors();//获取所有构造器
			for(Constructor con:cons) {
				if(con.getModifiers()==Modifier.PUBLIC)
					pubConsCount++;
				if(con.getModifiers()==Modifier.PRIVATE)
					priConsCount++;
			}
			/*获取属性信息*/
			Field[] fields = strObj.getDeclaredFields();//获取所有属性
			for(Field field:fields) {
				if(field.getModifiers()==Modifier.PUBLIC)
					pubFieldCount++;
				if(field.getModifiers()==Modifier.PRIVATE)
					priFieldCount++;
			}
			/*获取方法信息*/
			Method[] methods = strObj.getDeclaredMethods();//获取所有方法
			for(Method method:methods) {
				if(method.getModifiers()==Modifier.PUBLIC)
					pubMethodCount++;
				if(method.getModifiers()==Modifier.PRIVATE)
					priMethodCount++;
			}
			/*输出信息*/
			System.out.println("公有构造器数量"+pubConsCount);
			System.out.println("私有构造器数量"+priConsCount);
			System.out.println("公有属性数量"+pubFieldCount);
			System.out.println("私有属性数量"+priFieldCount);
			System.out.println("公有方法数量"+pubMethodCount);
			System.out.println("私有方法数量"+priMethodCount);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值