java的枚举和反射


枚举

 是一个被命名的整型常数的集合。枚举在生活中很常见,比如表示星期的SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY就是一个枚举。事先考虑到某一变量可能取的值,尽量用自然语言中含义清楚的单词来表示它的每一个值,这种方法被称为枚举方法,用这种方法定义的类型称为枚举类型。

 

注意:枚举是JDK5之后的一个重要特性,在枚举中可以限制一个类的对象产生的范围,加入枚举之后,java又对之前的类集进行了扩充,产生了一些新的枚举支持类——EnumSet、EnumMap。

 

定义枚举类型

格式:[public] enum 枚举类型名称{

                     枚举对象1,枚举对象2,……枚举对象n;

             

public classEnumDemo {
  public static void main(String []args){
     //取出周末
     Weekw = Week. SUNDAY;
     System.out.println(w);
 
     for(Week week:Week.values()){
     //用枚举.values()得到全部枚举的内容
       System.out.println(week);
     }
  }
 
}
 enum Week{
  SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY;
}


Enum类

 使用关键字enum可以定义一个枚举,实际上此关键字表示的是java.lang.Enum类型,即使用enum声明的枚举类型就相当于定义一个类,而此类默认继承java.lang.Enum类。

 

常用方法:

 

EnumMap类

 是Map接口的子类,与枚举类型键一起使用的专用 Map 实现。枚举映射中所有键都必须来自单个枚举类型,该枚举类型在创建映射时显式或隐式地指定。枚举映射在内部表示为数组。此表示形式非常紧凑且高效。

注意:在创建对象时必须指定操作的枚举类型。

publicEnumMap(Class<K>  keyType)

 

EnumSet类

是Set接口的子类,与枚举类型一起使用的专用 Set 实现。枚举 set 中所有键都必须来自单个枚举类型,该枚举类型在创建 set 时显式或隐式地指定。

 

注意:EnumSet不能直接实例化,要使用本类中提供的静态方法。

 

注意:枚举类不仅可以实现接口,还能在枚举类中定义抽象方法。

 

Java反射机制

反射就是把java类中的各种成分映射成相应的java类。简单说,就是通过一个class文件对象来使用该class文件中的构造方法,成员变量,成员方法。

优点:大大增强了程序的扩展性。

 

Class类:

类就是一组相关的属性和行为的集合,它是一个抽象的概念。由于多个class文件也会存在相同的内容,所以,我们就可以把多个class文件用一个类来描述,这个类就是Class类。

 

注意:所有类的对象实际上都是Class类的实例,所以所有的对象都可以转变为java.lang.Class类型表示。

       常用方法:

 

获取Class类文件的对象通常有三种方法:

(1)、Object类中的getClass()方法。

例如:

Person p = new Person();

Class c = p.getClass();

 

(2)、通过数据类型的一个静态的class属性。

例如:

Class c3= Person.class;

 

(3)、通过Class类的一个静态方法forName()。

例如:

Class c4 = Class.forName(“cn.Person”);

 

注意:程序中所有使用的具体类名在设计时(即开发时)无法确定,只有程序运行时才能确定,这时候就需要使用Class.forName去动态加载该类,这个类名通常是在配置文件中配置的。

 

使用反射的基本步骤:

(1)   获得字节码文件对象,就是获得Class对象。

(2)   获得类的成员属性、方法或者构造函数。

(3)   访问属性,调用构造函数创建对象,调用成员方法。

 

Constructor类

表示的是类中的构造方法,它的常用方法如下:

 

Field类

表示类中的属性。常用方法如下:

 

Method类

表示类中的成员方法。常用方法如下:

 

通过反射调用类中的方法:

public classPerson {
  private String name;
  private int age;
  public Person() {
     super();
  }
  public Person(String name, int age) {
     super();
     this.name = name;
     this.age = age;
  }
  public String sayHello(String name,int age){
     return "你好!我叫"+name+",今年"+age+"了。";
  }
 
  public String getName() {
     return name;
  }
  public void setName(String name) {
     this.name = name;
  }
  public int getAge() {
     return age;
  }
  public void setAge(int age) {
     this.age = age;
  }
 
}

import java.lang.reflect.Method;
 
public classPersonDemo {
  public static void main(String[] args) throws Exception {
     //实例化Class对象
     Classcl = Person.class;
    
     //通过Class对象获得sayHello()方法对像
     Methodmt = cl.getMethod("sayHello",String.class,int.class);
    
     //调用sayHello方法并输出结果
     System.out.println(mt.invoke(cl.newInstance(),"西门庆",38));
        
  }
}
 


暴力反射

 通过setAccessible()方法,将()中的值设为true,取消 Java 语言访问检查,就可以方位类中的私有属性。

 

反射操作数组

 反射机制不仅可以用在类上,还可以用在任意引用数据类型上,当然也包含数组。

注意:在java.lang.reflect中,使用Array类表示数组。

 


类加载器

 是Java运行时环境的一部分,负责动态加载Java类到Java虚拟机的内存空间中。类通常是按需加载,即第一次使用该类时才加载。在Proxy类的newProxyInstance()方法中需要一个ClassLoader类的实例,ClassLoader实际上对应的是类加载器。在java中主要有三种类加载器。

 

Bootstrap ClassLoader:采用C++编写,开发中看不到

Extension ClassLoader:进行扩展类的加载,对应的是jre\lib\ext目录

AppClassLoader:加载classpath指定的类,最常用的一种类加载器。

                                                                                                      

注意:jvm里有多个类加载,每个类加载可以负责加载特定位置的类,例如,bootstrap类加载负责加载jre/lib/rt.jar中的类,我们平时用的jdk中的类都位于rt.jar中。extclassloader负责加载jar/lib/ext/*.jar中的类,appclassloader负责classpath指定的目录或jar中的类。除了bootstrap之外,其他的类加载器本身也都是java类,它们的父类是ClassLoader。

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程之路从0到1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值