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();
}
}
}