JAVA基础加强篇——反射和枚举

来源:互联网 发布:mysql导入中文数据乱码 编辑:程序博客网 时间:2024/06/10 11:15

一、反射

反射机制

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

反射的基石:Class类

Java程序中的各个java类属于同一类事物,描述这类事物的java类名就是Class。注意:与小写class的区别,它是定义类时使用的关键字。

Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。

Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。

如何得到各个字节码对应的实例对象(Class类型)三种

创建顺序:字节码在硬盘中——>加载到内存中——>创建对象。

形式:Class class=字节码;

1、Class class1=Date.class;     //固定写法

2、Class class2=new Date().getClass();  //有了字节码创建的对象

3、Class class3=Class.forName(“java.uti.Date”);   //静态方法。(这是主要方式:因为写源程序时还不知道类的名字,写源程序时可以用一个字符串变量,然后从配置文件按中读取)

forName得到类的字节码有两种情况:

  1)、字节码已加载到内存中,无需加载,找到字节码返回。

  2)、虚拟机还没有字节码,用类加载器,将字节码缓存起来(以后无需再加载),使用forName方法获取。

反射具体实现

贴code

要反射的类

package cn.zjy.ClassDemo;public class ClassDemo {  public String name; private static int age;   public static int getAge() {return age;}public ClassDemo()     {    System.out.println("consruct ClassDemo()");     this.name = "hahaha";    this.age = 18;     }     public ClassDemo(String name)     {     System.out.println("consruct ClassDemo()"+name);     }     private ClassDemo(String name ,int age)     {     System.out.println("consruct ClassDemo()"+age+" "+name);      this.name=name;          }          public void mytest1()     {    System.out.println("implement mytest1");      }     public void mytest2(String name)     {     System.out.println("implement mytest2");     }     private void mytest3()     {     System.out.println("implement mytest3");      }     private static void mytest4()     {     System.out.println("implement mytest4");      }     private static void mytest5(String[] args)     {    System.out.println("implement mytest5");      }}

反射代码

package cn.zjy.ClassDemo;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import org.junit.Test;public class RegexDemo_1 {    @Test    public void test1() throws Exception    {    Class myclass = Class.forName("cn.zjy.ClassDemo.ClassDemo");    Constructor c = myclass.getConstructor(null);    c.newInstance(null);    }    @Test    public void test2() throws Exception    {    Class myclass = Class.forName("cn.zjy.ClassDemo.ClassDemo");    Constructor c = myclass.getConstructor(String.class);    c.newInstance("hello");    }    @Test    public void test3() throws Exception    {    Class myclass = Class.forName("cn.zjy.ClassDemo.ClassDemo");            ClassDemo a1=(ClassDemo)myclass.newInstance();    //ClassDemo a2=(ClassDemo)myclass.newInstance("hello");        Constructor c = myclass.getDeclaredConstructor(String.class,int.class);    c.setAccessible(true);    ClassDemo a = (ClassDemo)c.newInstance("hello",1);         System.out.println("the number of construct method is "+ myclass.getDeclaredConstructors().length);     System.out.println("the number of construct method is "+ myclass.getConstructors().length);        }    @Test    public void method_regex() throws Exception    {    Class myclass = ClassDemo.class;    ClassDemo demo1=(ClassDemo)myclass.newInstance();        Method m1=myclass.getMethod("mytest1",null);    m1.invoke(demo1, null);    Method m2 = myclass.getMethod("mytest2",String.class);    m2.invoke(demo1, "hello");        Method m3 = myclass.getDeclaredMethod("mytest3",null);    m3.setAccessible(true);    m3.invoke(demo1, null);    Method m4 = myclass.getDeclaredMethod("mytest4", null);    m4.setAccessible(true);    m4.invoke(null, null);            Method m5=myclass.getDeclaredMethod("mytest5", String[].class);    m5.setAccessible(true);//    m5.invoke(null, new Object[]{new String[]{"1","2"}});    m5.invoke(null, (Object)new String[]{"1","2"});    }    @Test    public void field_test() throws Exception    {     Class demo = ClassDemo.class;     ClassDemo mydemo = (ClassDemo)demo.newInstance();          Field f1 = demo.getField("name");     String name =(String)f1.get(mydemo);     System.out.println("i get teh name is "+name);          Field f2 = demo.getDeclaredField("age");     f2.setAccessible(true);     int myage =(Integer)f2.get(null);     System.out.println("i get the age is "+myage);          f1.set(mydemo,"hello");     f2.set(null,20);          System.out.println("my name is " + mydemo.name +"my age is "+mydemo.getAge());          }        }         


参考:http://www.cnblogs.com/M-Star/archive/2013/02/08/2909073.html


二、枚举

枚举类中的声明的每一个枚举值代表枚举类中的一个静态实例对象
枚举类的构造函数必须是私有的
枚举类也可以继承抽象类和接口
注意:枚举值必须放在第一行


为了方便记忆

/*Class MyEnum{private MyEnum(){};public static MyEnum A = new MyEnum();public static MyEnum B = new MyEnum();public static MyEnum C = new MyEnum();public static MyEnum D = new MyEnum();public static MyEnum E = new MyEnum();}*/

在实际编程中,往往存在着这样的“数据集”,它们的数值在程序中是稳定的,而且“数据集”中的元素是有限的。

例如星期一到星期日七个数据元素组成了一周的“数据集”,春夏秋冬四个数据元素组成了四季的“数据集”。

在java中如何更好的使用这些“数据集”呢?因此枚举便派上了用场,以下代码详细介绍了枚举的用法。


贴code

enum MyEnum{A("a","a"){public void mytest(){System.out.println("name is "+name+"sex is "+sex);}},B("b","b"){public void mytest(){System.out.println("name is "+name+"sex is "+sex);}},C("c","c"){public void mytest(){System.out.println("name is "+name+"sex is "+sex);}};//必须放在第一行,语法规定public String name;public  String sex;private MyEnum(String name,String sex){this.name =name ; this.sex = sex;}public abstract void mytest();//这里定义了一个抽象方法,由枚举常量的内部类来实现,从而实现特定的几个输出。}

测试类的

package cn.zjy.ClassDemo;import org.junit.Test;public class EnumTest {@Testpublic void enumtest(){MyEnum.A.mytest();//可以看到,由于构造函数是私有的,对于这个枚举我们只能调用这三个枚举常量。MyEnum.B.mytest();MyEnum.C.mytest();}}






0 0
原创粉丝点击