首先,一个难题:以下代码打印什么?
public class RecursiveStatic {
public static void main(String[] args) {
System.out.println(scale(5));
}
private static final long X = scale(10);
private static long scale(long value) {
return X * value;
}
}
Run Code Online (Sandbox Code Playgroud)
回答:
0
下面的剧透.
如果您打印X的规模(长),并重新定义X = scale(10) + 3,印刷品会X = 0那么X = 3.这意味着X暂时设置为0以后设置为3.这是违反final!
static修饰符与final修饰符结合使用,也用于定义常量.最终修饰符表示此字段的值不能更改.
来源:https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html [强调添加]
我的问题:这是一个错误吗?被final定义不清?
这是我感兴趣的代码.
X分配了两个不同的值:0和3.我认为这违反了 …
static块内初始化有什么区别:
public class staticTest {
static String s;
static int n;
static double d;
static {
s = "I'm static";
n = 500;
d = 4000.0001;
}
...
Run Code Online (Sandbox Code Playgroud)
和个人静态初始化:
public class staticTest {
static String s = "I'm static";
static int n = 500;
static double d = 4000.0001;
....
Run Code Online (Sandbox Code Playgroud) class Program {
static final int var;
static {
Program.var = 8; // Compilation error
}
public static void main(String[] args) {
int i;
i = Program.var;
System.out.println(Program.var);
}
}
Run Code Online (Sandbox Code Playgroud)
class Program {
static final int var;
static {
var = 8; //OK
}
public static void main(String[] args) {
System.out.println(Program.var);
}
}
Run Code Online (Sandbox Code Playgroud)
为什么案例1会导致编译错误?
当我试着写这样的东西时:
public interface MyInterface {
static {
System.out.println("Hello!");
}
}
Run Code Online (Sandbox Code Playgroud)
编译器无法编译它.
但是当我写这样的东西时:
interface MyInterface {
Integer iconst = Integer.valueOf(1);
}
Run Code Online (Sandbox Code Playgroud)
并反编译它,我看到静态初始化:
public interface MyInterface{
public static final java.lang.Integer i;
static {};
Code:
0: iconst_1
1: invokestatic #1; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
4: putstatic #2; //Field i:Ljava/lang/Integer;
7: return
}
Run Code Online (Sandbox Code Playgroud)
你能告诉我这个行为吗?
我最近遇到了Nifty Counter Idiom.我的理解是,这用于在标准库中实现全局变量,如cout,cerr等.由于专家选择了它,我认为它是一种非常强大的技术.
我试图了解使用更像Meyer Singleton的东西的优势.
例如,人们可以在头文件中:
inline Stream& getStream() { static Stream s; return s; }
static Stream& stream = getStream();
Run Code Online (Sandbox Code Playgroud)
优点是您不必担心引用计数,放置新的,或者有两个类,即代码更简单.既然没有这样做,我肯定有一个原因:
编辑:在阅读Yakk的答案时,我被提示编写以下代码,我将其作为快速演示添加到原始问题中.这是一个非常小的例子,展示了如何使用Meyer Singleton +全局引用在main之前进行初始化:http://coliru.stacked-crooked.com/a/a7f0c8f33ba42b7f.
我正在使用可以构建为共享库或静态库的C++库.该库使用工厂技术,其中静态对象在程序启动时自行注册并创建静态对象.
只要使用共享库,这样就可以正常工作.当使用静态版本时,没有任何静态对象被包含在最终程序中(因为它们没有被直接引用),因此它们的功能不可用.
有没有办法强制gcc在链接时包含库中的所有静态对象?
该库是开源的,我可以修改它,如果这有帮助.
我有2个班:
A类:
public class A {
static B b = new B();
static {
System.out.println("A static block");
}
public A() {
System.out.println("A constructor");
}
}
Run Code Online (Sandbox Code Playgroud)
B级:
public class B {
static {
System.out.println("B static block");
new A();
}
public B() {
System.out.println("B constructor");
}
}
Run Code Online (Sandbox Code Playgroud)
我创建一个Main类,它只创建新的A:
public class Main {
public static void main(String[] args) {
new A();
}
}
Run Code Online (Sandbox Code Playgroud)
我得到的输出是:
B static block
A constructor
B constructor
A static block
A constructor
Run Code Online (Sandbox Code Playgroud)
如您所见,A的构造函数在其静态初始化程序之前被调用.
我理解它与我创建的循环依赖有关,但我的印象是静态初始化器应该始终在构造函数之前运行.
发生这种情况的原因是什么(技术上在java实现中)?
是否建议一起避免静态初始化器?
创建Javascript对象的典型方法如下:
var map = new Object();
map[myKey1] = myObj1;
map[myKey2] = myObj2;
Run Code Online (Sandbox Code Playgroud)
我需要创建一个这样的映射,其中键和值都是字符串.我有一大堆但静态的对要添加到地图中.
有没有办法在Javascript中执行这样的操作:
var map = { { "aaa", "rrr" }, { "bbb", "ppp" } ... };
Run Code Online (Sandbox Code Playgroud)
或者我必须为每个条目执行类似的操作:
map["aaa"]="rrr";
map["bbb"]="ppp";
...
Run Code Online (Sandbox Code Playgroud)
基本上,剩余的Javascript代码将遍历此映射并根据"运行时"已知的标准提取值.如果这个循环作业有更好的数据结构,我也很感兴趣.我的目标是尽量减少代码.
考虑这个示例代码:
template<class D>
char register_(){
return D::get_dummy(); // static function
}
template<class D>
struct Foo{
static char const dummy;
};
template<class D>
char const Foo<D>::dummy = register_<D>();
struct Bar
: Foo<Bar>
{
static char const get_dummy() { return 42; }
};
Run Code Online (Sandbox Code Playgroud)
(也在Ideone上.)
我期望dummy得到尽快初始化为有一个具体的实例Foo,我有Bar.这个问题(以及最后的标准引用)解释得很清楚,为什么没有发生.
[...]特别是,除非静态数据成员本身以需要静态数据成员的定义存在的方式使用,否则不会发生静态数据成员的初始化(以及任何相关的副作用).
有没有办法强制 dummy初始化(有效调用register_)没有任何实例Bar或Foo(没有实例,所以没有构造函数欺骗),没有用户Foo需要以某种方式明确说明成员?额外的cookie,不需要派生类做任何事情.
编辑:找到一种方法,对派生类的影响最小:
struct Bar
: Foo<Bar>
{ // vvvvvvvvvvvv
static …Run Code Online (Sandbox Code Playgroud) 这个问题让我质疑我多年来一直遵循的做法.
对于函数本地静态const对象的线程安全初始化,我保护对象的实际构造,但不保护引用它的函数本地引用的初始化.像这样的东西:
namespace {
const some_type& create_const_thingy()
{
lock my_lock(some_mutex);
static const some_type the_const_thingy;
return the_const_thingy;
}
}
void use_const_thingy()
{
static const some_type& the_const_thingy = create_const_thingy();
// use the_const_thingy
}
Run Code Online (Sandbox Code Playgroud)
这个想法是锁定需要时间,如果引用被多个线程覆盖,那么无关紧要.
如果是的话,我会感兴趣的
我想知道这个的原因是我想知道我是否可以保留代码,或者我是否需要回去修复它.
对于探究的头脑:
我使用的许多这样的函数本地静态const对象是在首次使用时从const数组初始化并用于查找的映射.例如,我有一些XML解析器,其中标记名称字符串映射到enum值,因此我可以稍后switch覆盖标记的enum值.
由于我得到了一些关于该做什么的答案,但是没有得到我实际问题的答案(见上文1.和2.),我会对此开始赏金.还是那句话:
我不感兴趣,我能做什么,而不是,我真的想知道这个.
java ×5
c++ ×4
final ×2
c++11 ×1
concurrency ×1
constructor ×1
gcc ×1
interface ×1
javascript ×1
linux ×1
singleton ×1
static ×1
templates ×1