java动态性包括:
- 反射机制
- 动态编译
- 动态执行javascript代码
- 动态字节码
对动态性的理解
- 在程序运行过程中(而非编译时),动态地对对象创建及操作
动态语言:
- python
- javascript
非动态语言:
- c语言
- c++
- java(虽然不是动态语言,但有一定的动态性)
java反射机制的简单使用例子
自定义注解:
@Target(value = {ElementType.TYPE}) //作用域 类
@Retention(RetentionPolicy.RUNTIME) //保留策略 运行时有效
public @interface Table {
String value();
}
@Target(value = {ElementType.FIELD}) //作用域 描述域
@Retention(RetentionPolicy.RUNTIME) //保留策略 运行时有效
public @interface AnnoField {
String colName();
String type();
int length();
}
定义一个测试类:
@Table("student")
public class Student {
@AnnoField(colName="name",type="varchar",length=10)
private String name;
@AnnoField(colName="age",type="int",length=3)
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Student() {
}
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;
}
}
通过反射机制获得类的属性、方法和构造器
@SuppressWarnings("all")
public class TestReflection {
public static void main(String[] args) {
try {
//获得class对象
Class clazz = Class.forName("com.test.reflection.Student");
//获取类的属性
Field[] fs = clazz.getDeclaredFields(); //包括私有的 如果只获得public的 用getFields()
for(Field f : fs) {
System.out.println(f);
AnnoField field = f.getAnnotation(AnnoField.class);//获得属性的注解
System.out.println("列名:"+field.colName());
}
//获得类的方法
Method[] ms = clazz.getDeclaredMethods(); //获得所有的方法
for(Method m : ms) {
System.out.println(m);
}
Method m1 = clazz.getDeclaredMethod("setName", String.class);//获得指定的方法 ,第二个参数是区分重载的方法
System.out.println(m1);
//获得类的构造器
Constructor[] cs = clazz.getDeclaredConstructors();
for(Constructor c : cs) {
System.out.println(c);
}
//获得类的注解
Annotation[] annos = clazz.getDeclaredAnnotations();
for(Annotation anno : annos) {
System.out.println("类的注解"+anno);
}
}catch (Exception e) {
}
}
}
通过反射机制创建类及操作属性和方法
@SuppressWarnings("all")
public class TestReflection2 {
public static void main(String[] args) {
try {
//获得class对象
Class clazz = Class.forName("com.test.reflection.Student");
//通过反射API无参构造创建类
Student stu1 = (Student) clazz.newInstance();
//通过反射API有参构造创建类
Constructor c = clazz.getConstructor(String.class,int.class);
Student stu2 = (Student) c.newInstance("小明",12);
System.out.println(stu2.getAge());
//通过反射API执行方法
Method m1 = clazz.getMethod("setName", String.class);//先获得方法
m1.invoke(stu1, "小红");
System.out.println(clazz.getMethod("getName", null).invoke(stu1, null));
//通过反射API操作属性
Field f1 = clazz.getDeclaredField("age");
f1.setAccessible(true); //跳过安全检查,即可以操作非公有属性了。提高效率的常用方式
f1.set(stu1, 13);
System.out.println(stu1.getAge());
}catch (Exception e) {
}
}
}