首页 \ 问答 \ 在这种情况下,FindBugs的'JLM_JSR166_UTILCONCURRENT_MONITORENTER'可以安全地忽略(is FindBugs 'JLM_JSR166_UTILCONCURRENT_MONITORENTER' safe to ignore in this case)

在这种情况下,FindBugs的'JLM_JSR166_UTILCONCURRENT_MONITORENTER'可以安全地忽略(is FindBugs 'JLM_JSR166_UTILCONCURRENT_MONITORENTER' safe to ignore in this case)

我有一个我需要使用的库,它有一个静态值的危险初始化(类已被剥离到示例的最小值):

public TheirBaseClass {
    public static String PathToUse = null;

    public BaseClass(){
        PathToUse = "Configured";

        // ... 
        // do some other stuff with other side effects 
        // ...
    }
}

我有一个案例,我尝试从值ConfigValue读取而不实例化类(以避免一些副作用)。

Paths.get(TheirBaseClass.PathToUse).toFile()....

这会导致NullPointerException

因为我需要使用这个类,所以我希望继承它,并尝试采取措施确保在访问静态时进行初始化。

public MyBaseClass extends TheirBaseClass{

    private static final AtomicBoolean isInitialized = new AtomicBoolean(false);

    static {
        MyBaseClass.Initialize();
    }

    public static void Initialize(){
        // FindBugs does not like me synchronizing on a concurrent object
        synchronized(isInitialized){
            if( isInitialized.get() ){
                return;
            }
            new TheirBaseClass();
            isInitialized.set(true);
        }
    }

    public MyBaseClass(){
        super();
    }

}

这让我可以

MyBaseClass.Initialize();
Paths.get(MyBaseClass.PathToUse).toFile()....

这似乎运作得相当好(并解决了我们一直有的其他一些幻影缺陷)。 它允许TheirBaseClass自然地运行,同时允许我在我可能需要的几种情况下安全地强制初始化。

但是,当我针对此代码运行FindBugs时,我得到JLM_JSR166_UTILCONCURRENT_MONITORENTER 。 阅读完描述后,我同意使用AtomicBoolean可能会有危险,因为其他人可能会改变这个值,但......

  1. 我认为在这种情况下可以安全地忽略(但有疑问)
  2. 我通常更喜欢重写代码而不是放置一个忽略标记

我实际上在做一些危险的事情(而且看不到它)? 有一个更好的方法吗?

不幸的是,使用不同的TheirBaseClass不是一种选择。

有关


I have a library that I am required to use that has a dangerous initialization of a static value (the classes have been stripped down to the minimum for the example):

public TheirBaseClass {
    public static String PathToUse = null;

    public BaseClass(){
        PathToUse = "Configured";

        // ... 
        // do some other stuff with other side effects 
        // ...
    }
}

I have a case where I attempt to read from the value ConfigValue without instantiating the class (to avoid some of the sideeffects).

Paths.get(TheirBaseClass.PathToUse).toFile()....

This causes a NullPointerException

Because I am required to use this class, I am looking to inherit from it, and attempt to take action to ensure that initialization has taken place when accessing the static.

public MyBaseClass extends TheirBaseClass{

    private static final AtomicBoolean isInitialized = new AtomicBoolean(false);

    static {
        MyBaseClass.Initialize();
    }

    public static void Initialize(){
        // FindBugs does not like me synchronizing on a concurrent object
        synchronized(isInitialized){
            if( isInitialized.get() ){
                return;
            }
            new TheirBaseClass();
            isInitialized.set(true);
        }
    }

    public MyBaseClass(){
        super();
    }

}

Which allows me to

MyBaseClass.Initialize();
Paths.get(MyBaseClass.PathToUse).toFile()....

This seems to be working reasonably well (and resolves some other phantom defects we've been having). It allows TheirBaseClass to function naturally, while allowing me to safely force initialization in the couple of cases I may need to.

However when I run FindBugs against this code, I get JLM_JSR166_UTILCONCURRENT_MONITORENTER. After reading the description, I agree that the use of AtomicBoolean could be dangerous because someone else could change the value, but...

  1. I think its safe to ignore in this case (but have a doubt)
  2. I generally prefer to rewrite code than put an ignore marker in place

Am I actually doing something dangerous (and just don't see it)? Is there a better way to do this?

Unfortunately, using a different TheirBaseClass is not an option.

Related


原文:https://stackoverflow.com/questions/39149166
更新时间:2023-07-30 19:07

最满意答案

活动代表团:

$(document).on("click", ".loadMorePhotos", function(){
        alert("ok malaka!");
});

由于您的元素是动态创建的,因此您必须将点击处理程序绑定到DOM就绪的元素(在本例中为document


Event delegation:

$(document).on("click", ".loadMorePhotos", function(){
        alert("ok malaka!");
});

Because your elements are dynamically created, you have to bind the click handler to an element that already exists at DOM ready (in this case, document)

相关问答

更多
  • 解决整个问题的另一个方法是不打扰解绑和重新绑定,只是使用“禁用”标志: $(document).ready(function(){ var clickDisabled = false; $('#click').click(function(){ if (clickDisabled) return; // do your real click processing here clickDisabled = true; setT ...
  • 首先,不要使用事件属性! 请改用addEventListener( MDN )作为现代标准。 然后你应该定义一个单独的处理函数(让我们说onClick )将它与你的元素绑定: var cancelElt = document.getElementById('modal-cancel'); var closeElt = document.getElementById('modal-close'); var onClick = function () { alert('Hello!'); }; cance ...
  • 在后面的代码中,在您的类中声明一个事件: Public Event Click(sender as object, e as EventArgs) 然后,当您处理constinuent按钮的click事件时,请引发事件 Sub btnButton_Click(sender as object, e as EventArgs) Handles btnButton.Click RaiseEvent Me.Click(Me, EventArgs) End Sub In the code behind, ...
  • 活动代表团: $(document).on("click", ".loadMorePhotos", function(){ alert("ok malaka!"); }); 由于您的元素是动态创建的,因此您必须将点击处理程序绑定到DOM就绪的元素(在本例中为document ) Event delegation: $(document).on("click", ".loadMorePhotos", function(){ alert("ok malaka!"); }); ...
  • 如果你打算有多个其他类,如button--3 , …4 ... …15 , 你必须使用“按钮”来定位所有开始class( ^= )的div元素: (请注意,您也可以在CSS中执行此操作!) var allButtons = document.querySelectorAll('div[class^=button]'); console.log("Found", allButtons.length, "div which class starts with “button”."); for (var ...
  • 要一次选择4个按钮,请编写以下内容: $('#button1, #button2, #button3, #button4').click(function(event){ /* code here */ }); 如果您需要确定按下哪个按钮,请写下如下内容: $('#button1, #button2, #button3, #button4').click(function(event){ if($(event.target).attr('id')=='button1'){ /* ...
  • 你的代码不起作用,因为变量i的范围总是在处理程序中的num_button 。 您可以通过将其包装在closure包中来修复它,但如何通过添加类并使用按钮的id来简化它。 function myFunc( target_div, num_buttons ) { var buttons=""; for ( var i=0; i
  • 因为没有定义Tag的Button和ToolStripMenuItem的公共基类或接口,所以需要进行强制转换: internal static object GetTag(object sender) { Button button = sender as Button; ToolStripItem tsi = sender as ToolStripItem; if (button != null) return button.Tag; if (tsi != null) re ...
  • 将Button.Click处理程序分配给StackPanel时,处理程序方法的sender参数不是Button,因此(sender as Button)返回null。 您可以编写(e.OriginalSource as Button) ,通过它可以更简单地将Click处理程序分配给Style中的EventSetter所有按钮: