Безопасное приведение к int в Java

Вы можете достичь этого с помощью функции Перехват контейнера DI, такого как Castle Windsor . Действительно, можно сконфигурировать контейнер таким образом, чтобы все классы, у которых есть метод, украшенный определенным атрибутом, были перехвачены.

Что касается пункта № 3, OP попросил решение без рамки AOP. Я предположил в следующем ответе, что следует избегать: Aspect, JointPoint, PointCut и т. Д. Согласно документации перехвата от CastleWindsor , ни один из них не требуется для выполнения того, что задано.

Настроить общую регистрацию Interceptor на основе наличия атрибута:

public class RequireInterception : IContributeComponentModelConstruction
{
    public void ProcessModel(IKernel kernel, ComponentModel model)
    {
        if (HasAMethodDecoratedByLoggingAttribute(model.Implementation))
        {
            model.Interceptors.Add(new InterceptorReference(typeof(ConsoleLoggingInterceptor)));
            model.Interceptors.Add(new InterceptorReference(typeof(NLogInterceptor)));
        }
    }

    private bool HasAMethodDecoratedByLoggingAttribute(Type implementation)
    {
        foreach (var memberInfo in implementation.GetMembers())
        {
            var attribute = memberInfo.GetCustomAttributes(typeof(LogAttribute)).FirstOrDefault() as LogAttribute;
            if (attribute != null)
            {
                return true;
            }
        }

        return false;
    }
}

Добавить созданный IContributeComponentModelConstruction в контейнер

container.Kernel.ComponentModelBuilder.AddContributor(new RequireInterception());

И вы можете делать все, что хотите в самом перехватчике

public class ConsoleLoggingInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        Console.Writeline("Log before executing");
        invocation.Proceed();
        Console.Writeline("Log after executing");
    }
}

Добавить атрибут регистрации для вашего метода в журнал

 public class Traced 
 {
     [Log]
     public void Method1(String name, Int32 value) { }

     [Log]
     public void Method2(Object object) { }
 }

Обратите внимание, что некоторая обработка атрибута потребуется, если только какой-либо метод класса необходимо перехватить. По умолчанию все общедоступные методы будут перехвачены.

461
задан Mark 9 February 2017 в 09:52
поделиться

3 ответа

Думаю, я бы сделал это так же просто, как:

public static int safeLongToInt(long l) {
    if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
        throw new IllegalArgumentException
            (l + " cannot be cast to int without changing its value.");
    }
    return (int) l;
}

Я думаю, что это выражает намерение более ясно, чем повторное использование ... но это несколько субъективно.

Примечание о потенциале интерес - в C # это будет просто:

return checked ((int) l);
304
ответ дан 22 November 2019 в 22:53
поделиться

Я утверждаю, что очевидный способ увидеть, изменило ли значение при приведении значения, было бы приведение и проверка результата. Однако я бы удалил ненужное приведение при сравнении. Мне также не очень нравятся однобуквенные имена переменных (исключение x и y , но не тогда, когда они означают строку и столбец (иногда соответственно)).

public static int intValue(long value) {
    int valueInt = (int)value;
    if (valueInt != value) {
        throw new IllegalArgumentException(
            "The long value "+value+" is not within range of the int type"
        );
    }
    return valueInt;
}

Однако на самом деле Я бы хотел избежать этого преобразования, если это вообще возможно. Очевидно, иногда это невозможно,

7
ответ дан 22 November 2019 в 22:53
поделиться

Целочисленные типы Java представлены со знаком. При вводе между 2 31 и 2 32 (или -2 31 и -2 32 ) приведение будет успешным, но ваш тест потерпит неудачу.

Что нужно проверить, так это то, все ли старшие биты long одинаковы:

public static final long LONG_HIGH_BITS = 0xFFFFFFFF80000000L;
public static int safeLongToInt(long l) {
    if ((l & LONG_HIGH_BITS) == 0 || (l & LONG_HIGH_BITS) == LONG_HIGH_BITS) {
        return (int) l;
    } else {
        throw new IllegalArgumentException("...");
    }
}
2
ответ дан 22 November 2019 в 22:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: