您的位置:首页 > 编程语言 > Java开发

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

2014-01-01 21:08 357 查看
一、反射


反射机制

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 {
@Test
public void enumtest()
{
MyEnum.A.mytest();//可以看到,由于构造函数是私有的,对于这个枚举我们只能调用这三个枚举常量。
MyEnum.B.mytest();
MyEnum.C.mytest();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  JAVA 基础加强
相关文章推荐