11

古いコードを読み取ってスキャンすると、次のコード行が表示されました。

public static void replaceNull(Object obj)
{
    if (obj == null)
    {
        return;
    }

    Field[] fields = obj.getClass().getDeclaredFields();
    if (fields != null)
    {
        for (Field field : fields)
        {
            field.setAccessible(true);
            Class<?> fieldType = field.getType();
            try
            {
                if (field.get(obj) == null)
                {
                    setDefaultValue(obj, field, fieldType);
                }
            } catch (IllegalArgumentException e)
            {
                logger. error("failed replacing null :"+ e.getMessage(),e);
            } catch (IllegalAccessException e)
            {
                logger. error("failed replacing null :"+ e.getMessage(),e);
            }

        }
    }
}

   private static void setDefaultValue(Object obj, Field field, Class<?> fieldType) throws IllegalAccessException
{
    if (fieldType == String.class)
    {
        field.set(obj, CommonConstants.BLANK);

    } else if (fieldType == Date.class)
    {
        field.set(obj, new Date());
    } else if (fieldType == Long.class)
    {
        field.setLong(obj, 0L);
    } else if (fieldType == Integer.class)
    {
        field.setInt(obj, 0);
    } else if (fieldType == BigDecimal.class)
    {
        field.set(obj, new BigDecimal("0.0"));
    }
}

プログラムの流れから、値が null の場合、ライターはオブジェクトのすべてのデータ メンバーのデフォルト値を作成したいと考えているようです。

FindBugs を使用してスキャンすると、findbugs は「DP_DO_INSIDE_DO_PRIVILEGED」を setAccessible(true) に関する次の説明とともに報告しました。

悪い習慣 - doPrivileged ブロック内でのみ呼び出されるべきメソッドが呼び出される プラグイン: findbugs キー: DP_DO_INSIDE_DO_PRIVILEGED このコードは、セキュリティ許可チェックを必要とするメソッドを呼び出します。このコードにセキュリティ パーミッションが付与されても、セキュリティ パーミッションを持たないコードによって呼び出される可能性がある場合は、doPrivileged ブロック内で呼び出しを行う必要があります。

私の質問はなぜこれが悪いのですか?また、どのように解決すればよいですか?

4

2 に答える 2

9

の Javadoc からfield#setAccessible(boolean):

まず、セキュリティ マネージャがある場合、その checkPermission メソッドが ReflectPermission("suppressAccessChecks") 権限で呼び出されます。

がインストールされていなくてもSecurityManager、プログラムは正常に動作します。ただし、コードが共有ライブラリとして記述されていて、セキュリティ マネージャが設定されているモジュールでたまたま使用されているとします。この場合、field.setAccessible(true)コード内のこの操作およびその他の操作が信頼できるコードと見なされていても、アクセスが拒否される可能性があります。そのため、FindBugs はこの警告を発します。

field.setAccessible(true)呼び出し元コードのアクセス許可に関係なく、常にアクセス許可が付与されることを保証するために、ステートメントを a 内にラップできAccessController.doPrivilegedます ( fieldfinal にする必要があります)。

AccessController.doPrivileged(new PrivilegedAction() {
    @Override
    public Object run() {
        field.setAccessible(true);
        return null;
    }
});
于 2014-11-08T22:15:43.973 に答える
3

上記の受け入れられた回答に加えて、 Java 1.7+ ラムダ式を使用すると、次の方法で同じことが実現できます。

AccessController.doPrivileged((PrivilegedAction) () -> {
    field.setAccessible(true);
    return null;
});
于 2017-03-25T06:15:32.310 に答える