在类被实例化前动态改变其静态常量

博客围绕byte、class等内容展开解密相关探讨,但具体内容缺失。推测可能涉及信息技术领域中对byte数据类型和class类的深入解析。
在类被实例化前动态改变其静态常量
efly 原创  (参与分:1044,专家分:1840)   发表:2002-11-13 下午5:37   更新:2002-11-14 下午5:02   版本:1.1   阅读:3118

被动态改变的类如下:
public class ScrollImage implements Face {

private static String TEST = "TEST";

public static void change(String change){
TEST=change;
}
public void myFace(String describe) {
}

/**
* Constructor for ScrollImage.
*/
public ScrollImage() {
super();
System.out.println(":))"+TEST);
show();
}
...
注意 通常使用new ScrollImage()时会输出::))TEST
我的目的要通过类加载来改变它的输出,实际上是改变了静态常量的值,也相当于改变了任何一个实例对该常量的引用值。

先判断该类是否为我们需要动态改变的类
Class cImage;
Object oImage;
MyLoader loader = new MyLoader();

cImage =
loader.load("ScrollImage.class", "cn.com.efly.swt.ScrollImage");
if (Face.class.isAssignableFrom(cImage))
System.out.println(":):)");

改变它:
String arg = "changed";
/**也可以通过直接访问常量来改变它,但是要修改常量的可见为public
*My ClassLoader:
*public class MyLoader extends ClassLoader {
*    static int maxsize = 10000;
*    public Class load(String namefile, String classname)
*        throws java.lang.Exception {
*        try {
*            //进行判断这个class是否已经调入,已经有就直接返回,不然就调入
*            Class ctmp = this.findLoadedClass(classname);
*            System.out.println(ctmp.getName() + " is load");
*            return ctmp;
*        } catch (Exception e) {
*            //System.out.println(e);
*        }
*        java.io.FileInputStream in = new java.io.FileInputStream(namefile);
*        byte[] classbyte = new byte[maxsize];
*        //实际应用时完全可以对一个文件进行加解密处理,只要保证使用*defineClass时classbyte中
*        //已经解密后的内容就可以
*        int readsize;
*        readsize = in.read(classbyte);
*        // System.out.println("读文件长:"+readsize);
*        in.close();
*        return defineClass(classname, classbyte, 0, readsize);
*    }
*}
*/
//cImage.getField("TEST").set(null,"Changed");
java.lang.reflect.Method change =
cImage.getMethod("change", new Class[] { String.class });
change.invoke(change, new Object[] { arg });
实例化该类,可以看到结果:
oImage = cImage.newInstance();
结果输出:
:):)
:))changed

总结:改方法可以用来解决一些特殊情况下遇到的问题,但是我不鼓励大家使用。在我新的设计中已经不考虑使用改方法,它对结构没有任何好处。

<think>嗯,我现在要理解C++中静态常量整型数据成员在内初始化的规则。首先,根据之看到的引用内容,好像C++11之的标准只允许静态常量整型成员在内初始化。那为什么会这样呢? 我记得在引用[4]中提到,定义只是一个框架,不会分配存储空间,所以非静态成员在内初始化可能有问题。但静态成员是属于的,不是对象实例的一部分,所以可能处理方式不同。而常量整型可能因为编译时就能确定值,所以允许在内初始化。 比如引用[1]说,静态成员必须在外初始化,但静态常量整型可以在内初始化。这可能是因为这些型的值在编译期就能确定,不需要运行时计算,所以编译器可以处理。而非整型或者非静态的可能需要更复杂的内存分配,所以不能在内初始化。 然后引用[2]和[3]的例子显示,静态成员需要在外初始化,除了静态常量整型。比如在base中,const static int c可以在内初始化为9,而static int b需要在外初始化。而引用[4]提到的错误C2864说明在C++11之,非静态常量整型也不能在内初始化,只能用构造函数初始化列表或者在C++11之后支持内初始化。 所以总结一下,规则可能如下: 1. 静态常量整型(static const int,或者枚举型)可以在内初始化。 2. 非静态常量成员必须在构造函数初始化列表里初始化。 3. C++11之后,允许非静态成员在内初始化,但之不行。 4. 静态非整型或非常量成员必须在外定义和初始化。 那为什么会允许静态常量整型在内初始化呢?可能是因为它们既是常量又是整型,编译期就能确定值,不需要分配存储空间,似于符号常量。而其他型的静态成员需要分配存储空间,所以必须外定义。 比如,在内声明static const int size = 100; 这样的成员可以作为数组的大小,因为编译器需要知道这个值在编译期。而如果是static const double,可能就不允许,除非使用C++11或更高版本? 不过根据引用[2],例子中的const static int c=9是正确的,而引用[4]提到VS2010不支持非静态内初始化,所以可能整型包括枚举,但不包括其他型如浮点数或字符串。 另外,C++11扩展了内初始化的支持,允许非静态成员在声明时初始化,所以现在可能有更多的灵活性。但在旧标准中,只有静态常量整型可以这样做。 这样看来,规则的核心在于存储空间的分配和编译时的确定性。静态常量整型在编译时就能确定,所以不需要在外分配存储空间,而其他型的静态成员需要在外定义,因为它们需要存储空间,并且可能涉及更复杂的初始化过程。 例如,引用[3]中的例子显示,非常量静态成员必须在外初始化,因为它们不是常量,无法在编译时确定值,必须有一个单独的定义来分配存储空间。而静态常量整型可以作为编译时常量,不需要单独的定义,除非需要取地址等情况。 但是,如果静态常量整型被odr-used(比如取地址),可能还是需要在外定义。否则,可能不需要。这可能是一个例外情况。 总的来说,C++的规则在这里是为了平衡编译器的能力和灵活性,确保成员的正确初始化和存储分配。</think>### C++静态常量整型数据成员内初始化规则解析 #### 1. **核心规则** 在**C++11标准之**,**只有静态常量整型数据成员**(`static const integral type`)才允许在内直接初始化[^4]。例如: ```cpp class Example { public: static const int MAX_SIZE = 100; // ✔️ 合法 static const double PI = 3.14; // ❌ 非法(非整型) }; ``` - **静态性**:成员属于而非对象,无需实例化即可使用。 - **常量性**:值在编译期确定,不可修改。 - **整型型**:包括`int`、`char`、`enum`及其`const`修饰的变体[^4]。 #### 2. **技术原理** - **存储分配**:定义不分配内存,静态常量整型因其**编译期可计算性**,可视为符号常量,无需额外存储[^1]。 - **语法兼容性**:允许用此成员定义数组大小等场景,例如: ```cpp class Buffer { public: static const int SIZE = 1024; char data[SIZE]; // 直接使用内初始化的静态常量 }; ``` #### 3. **例外与限制** - **ODR-Use(单一定义规则使用)**:若需取地址或绑定引用,仍需在外定义(但无需重复初始化): ```cpp // 内声明 class Example { public: static const int VALUE = 42; }; // 外定义(仅需一次) const int Example::VALUE; // 不需要赋值 ``` - **C++11扩展**:允许非静态成员(含非整型)内初始化[^4]: ```cpp class PostCpp11 { public: int count = 0; // ✔️ 合法(C++11+) double ratio{1.618}; // ✔️ 合法(C++11+) }; ``` #### 4. **错误示例与修复** - **错误代码(C++11)**: ```cpp class ErrorClass { public: static int id = 10; // ❌ 非常量 const float PI = 3.14; // ❌ 非静态且非整型 }; ``` - **修复方法**: ```cpp class FixedClass { public: static const int id = 10; // ✔️ 静态常量整型 const float PI; // ✔️ 通过构造函数初始化 FixedClass() : PI(3.14) {} }; ``` #### 5. **对比其他成员型** | 成员型 | 内初始化(C++11) | 外初始化要求 | |---------------------------|-----------------------|----------------------| | 静态常量整型 | ✔️ | 仅ODR-Use时需要 | | 静态常量非整型(如double)| ❌ | ✔️ | | 非静态常量成员 | ❌ | 构造函数初始化列表 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值