动态语言VS静态语言

动态语言

概述

是一类在运行时可以改变其结构的语言:例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。通俗点说就是在运行时代码可以根据某些条件改变自身结构。

主要动态语言:Object-C、C#、JavaScript、PHP、Python、Erlang。

示例

Python 被认为是一种动态语言,因为它允许在运行时改变其结构,包括引入新的函数、对象,以及修改已有的函数和对象的行为。

动态类型系统
x = 5
print(type(x))  # 输出 <class 'int'>

x = "Hello"
print(type(x))  # 输出 <class 'str'>
动态创建函数和对象

可以使用内置的 exec() 函数来执行动态创建的代码。

# 动态创建函数
def greet(name):
    print(f"Hello, {name}!")

func_name = "greet"
exec(f"{func_name}('Alice')")  # 输出 Hello, Alice!

# 动态创建对象
class DynamicClass:
    pass

obj_name = "my_obj"
exec(f"{obj_name} = DynamicClass()")
print(my_obj)  # 输出 <__main__.DynamicClass object at 0x...>

修改函数和对象的行为
class MyClass:
    def say_hello(self):
        print("Hello from MyClass!")

obj = MyClass()
obj.say_hello()  # 输出 Hello from MyClass!

# 动态添加方法
def new_method(self):
    print("This is a new method!")

MyClass.new_method = new_method
obj.new_method()  # 输出 This is a new method!

静态语言

概述

与动态语言相对应的,运行时结构不可变的语言就是静态语言。如Java、C、C++。

Java不是动态语言,但Java可以称之为“准动态语言”。即Java有一定的动态性,我们可以利用反射机制、字节码操作获得类似动态语言的特性。Java的动态性让编程的时候更加灵活!

示例(“准动态”)

反射机制

Java的反射机制允许您在运行时检查和操作类、方法、字段等。这使得您可以在运行时动态地获取类的信息和执行类的方法。

import java.lang.reflect.Method;

public class ReflectExample {
    public static void main(String[] args) throws Exception {
        // 获取类的Class对象
        Class<?> clazz = Class.forName("com.example.MyClass");

        // 创建类的实例
        Object obj = clazz.getDeclaredConstructor().newInstance();

        // 获取并调用类的方法
        Method method = clazz.getMethod("sayHello");
        method.invoke(obj);
    }
}

动态代理

Java允许使用动态代理来创建在运行时生成的代理类,以实现对接口的方法调用的拦截和增强。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface MyInterface {
    void doSomething();
}

class MyImplementation implements MyInterface {
    public void doSomething() {
        System.out.println("Real implementation is called.");
    }
}

public class DynamicProxyExample {
    public static void main(String[] args) {
        MyInterface realObject = new MyImplementation();

        MyInterface proxyObject = (MyInterface) Proxy.newProxyInstance(
                MyInterface.class.getClassLoader(),
                new Class[]{MyInterface.class},
                new InvocationHandler() {
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("Proxy is called.");
                        return method.invoke(realObject, args);
                    }
                });

        proxyObject.doSomething();
    }
}
字节码操作

使用字节码操作库(例如ASM、CGLIB),可以在运行时生成、修改和加载类的字节码,以实现对类的动态修改。

posted @ 2023-09-16 11:09  岸南  阅读(62)  评论(0)    收藏  举报