小编Tav*_*nes的帖子

在Jackson的反射反序列化之上进行自定义反序列化

我想在使用Jackson 1.9反序列化特定类型时运行一些自定义代码.但是,我不想手写整个反序列化器,只需添加到默认行为.但是,尝试以JsonDeserializer天真的方式执行此操作会导致无限递归.目前,我的方法使用完全独立ObjectMapper,但感觉就像一个巨大的黑客.

private static class SpecialDeserializer extends JsonDeserializer<Special> {
    @Override
    public Special deserialize(JsonParser jp, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        JsonNode jsonNode = jp.readValueAsTree();
        ObjectMapper otherMapper = getOtherMapper();
        Special special = otherMapper.readValue(jsonNode, Special.class);
        special.setJsonNode(jsonNode);
        return special;
    }
}
Run Code Online (Sandbox Code Playgroud)

java json jackson

8
推荐指数
1
解决办法
783
查看次数

如何从Java 8中的getAnnotatedParameterTypes()获取泛型类型信息?

它似乎getAnnotatedParameterTypes()返回一个包含AnnotatedType原始类型而不是泛型类型的s 数组.例如:

public <T> void genericMethod(T t) {
}

@Test
public void testAnnotatedTypes() throws ReflectiveOperationException {
    Method method = getClass().getMethod("genericMethod", Object.class);

    Type type = method.getGenericParameterTypes()[0];
    assertTrue(type instanceof TypeVariable);

    AnnotatedType annotatedType = method.getAnnotatedParameterTypes()[0];

    // This fails; annotatedType implements only AnnotatedType
    assertTrue(annotatedType instanceof AnnotatedTypeVariable);

    // This fails too; type is a TypeVariable while annotatedType.getType() is
    // Object.class
    assertEquals(type, annotatedType.getType());
}
Run Code Online (Sandbox Code Playgroud)

分歧的原因是什么getGenericParameterTypes()

java generics reflection java-8 type-annotation

8
推荐指数
1
解决办法
949
查看次数

如何通过非缩小转换来编写类型特征以检查类型是否可以转换为另一个类型?

C++ 11引入了统一初始化,它具有禁止隐式缩小转换的理想特性.例如,int i{2.2}应该是一个错误.

不幸的是,出于向后兼容性的原因,C++ 03,GCC从4.7开始只给出了这些警告.

GCC的文档表明此扩展不适用于SFINAE环境,但它似乎是错误的:

#include <type_traits>
#include <utility>

template <typename From, typename To>
class is_list_convertible_helper
{
  template <typename To2>
  static void requires_conversion(To2 t);

  template <typename From2, typename To2,
      typename = decltype(requires_conversion<To2>({std::declval<From2>()}))>
  //                                               ^ Braced initializer
  static std::true_type helper(int);

  template <typename From2, typename To2>
  static std::false_type helper(...);

public:
  using type = decltype(helper<From, To>(0));
};

template <typename From, typename To>
class is_list_convertible
  : public is_list_convertible_helper<From, To>::type
{ };

static_assert(!is_list_convertible<double, int>::value,
    "double -> int is narrowing!");
Run Code Online (Sandbox Code Playgroud)

GCC …

c++ gcc sfinae type-traits c++11

8
推荐指数
1
解决办法
693
查看次数

是否可以将int**和const int**替换为别名?

我的理解是这样的事情是可以的:

const int ci = 42;
const int *cip = &ci;
int *ip = (int *)cip;
int j = *ip;
Run Code Online (Sandbox Code Playgroud)

那这个呢?

const int ci = 42;
const int *cip = &ci;
const int **cipp = &cip;
int **ipp = (int **)cipp;
int j = **ipp;
Run Code Online (Sandbox Code Playgroud)

c const strict-aliasing undefined-behavior language-lawyer

8
推荐指数
1
解决办法
172
查看次数

std :: vector :: emplace()是否真的在抛出移动构造函数/赋值运算符时提供强大的异常保证?

根据cppreference.com,std :: vector :: emplace()无条件地提供强大的异常保证:

如果抛出异常(例如,通过构造函数),则容器保持不变,就好像从未调用此函数一样(强异常保证).

但是,GCC 7.1.1在实践中似乎并非如此.以下程序:

#include <iostream>
#include <vector>

struct ugly
{
  int i;

  ugly(int i) : i{i} { }

  ugly(const ugly& other) = default;

  ugly& operator=(ugly&& other) {
    if (other.i == 3) {
      throw other.i;
    }
    i = other.i;
    return *this;
  }

  ugly& operator=(const ugly& other) = default;
};

int main() {
  std::vector<ugly> vec;
  vec.reserve(6);
  vec.emplace_back(0);
  vec.emplace_back(1);
  vec.emplace_back(2);
  vec.emplace_back(4);
  vec.emplace_back(5);

  try {
    vec.emplace(vec.begin() + 3, 3);
  } catch (int i) {
  }

  for (const auto& …
Run Code Online (Sandbox Code Playgroud)

c++ vector libstdc++ c++11

8
推荐指数
1
解决办法
546
查看次数

交叉编译时是否有gcc选项可以打印目标三元组?

gcc -dumpmachine几乎是完美的,但它不尊重影响目标的旗帜.另一方面,clang确实:

$ gcc -dumpmachine
x86_64-unknown-linux-gnu
$ gcc -dumpmachine -m32
x86_64-unknown-linux-gnu
Run Code Online (Sandbox Code Playgroud)
$ clang -dumpmachine
x86_64-unknown-linux-gnu
$ clang -dumpmachine -m32
i386-unknown-linux-gnu
Run Code Online (Sandbox Code Playgroud)

gcc clang cross-compiling compiler-options

7
推荐指数
1
解决办法
1093
查看次数

通过加入析构函数来等待异步工作是否安全?

假设我有一个可以异步运行某些代码的类,并且该异步代码使用该类实例来执行调用成员函数,读取数据成员等操作.显然,类实例必须比后台线程更长,以便进行这些访问.安全.通过在析构函数中加入后台线程来确保这一点就足够了吗?例如:

#include <iostream>
#include <thread>

class foo final
{
public:
    foo() = default;

    void bar() {
        std::cout << "Hopefully there's nothing wrong with using " << this << "\n";
    }

    void bar_async() {
        if (!m_thread.joinable()) {
            m_thread = std::thread{&foo::bar, this};
        }
    }

    ~foo() {
        if (m_thread.joinable()) {
            std::cout << "Waiting for " << m_thread.get_id() << "\n";
            m_thread.join();
        }
    }

private:
    std::thread m_thread;
};

int main() {
    foo f;
    f.bar_async();
}
Run Code Online (Sandbox Code Playgroud)

具体来说,我担心对象生存期规则:

对于析构函数不是微不足道的类类型的任何对象,生命周期在析构函数的执行开始时结束.

...在对象的生命周期结束之后,在重用或释放对象占用的存储之前,以下使用标识该对象的glvalue表达式是未定义的:...

  • 访问非静态数据成员或调用非静态成员函数.

但对我来说,严格阅读上述内容也意味着this->bar()从内部~foo() …

c++ multithreading thread-safety object-lifetime c++11

7
推荐指数
1
解决办法
380
查看次数

为什么不允许转换为"GenericType <?>"?

此代码导致javac编译错误(但值得注意的是,不是Eclipse 4.2.2!):

public interface Foo<T> {
}

class Bar<T> implements Foo<Iterable<T>> {
}

class Test {
    void test(Foo<? extends Iterable<? extends String>> foo) {
        Bar<?> bar = (Bar<?>) foo;
    }
}
Run Code Online (Sandbox Code Playgroud)

来自javac的错误是这样的:

Foo.java:9: error: inconvertible types
        Bar<?> bar = (Bar<?>) foo;
                              ^
  required: Bar<?>
  found:    Foo<CAP#1>
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Iterable<? extends String> from capture of ? extends Iterable<? extends String>
Run Code Online (Sandbox Code Playgroud)

将转换更改为(Bar) foo(即使用原始类型)允许代码编译,就像更改类型一样foo简单Foo<? extends Iterable<?>>.

编辑:非常有趣,这个简单的改变导致Eclipse拒绝,但javac接受:

void test(Foo<Iterable<String>> foo) { …
Run Code Online (Sandbox Code Playgroud)

java eclipse generics

6
推荐指数
1
解决办法
162
查看次数

java.lang.Class泛型和通配符

为什么以下代码无法编译?

interface Iface<T> { }

class Impl<T> implements Iface<T> { }

class TestCase {
    static Class<? extends Iface<?>> clazz = Impl.class;
}
Run Code Online (Sandbox Code Playgroud)

错误是

java:不兼容的类型:java.lang.Class<Impl>无法转换为java.lang.Class<? extends Iface<?>>

但我不明白为什么通配符不能捕获.

java generics bounded-wildcard

6
推荐指数
1
解决办法
842
查看次数

使用替换的运算符new进行Clang链接时优化会导致valgrind中的free()/ delete不匹配

当使用clang 3.5.0和-flto并使用共享库进行链接时,共享库中的调用似乎operator delete不会遵循与operator new主对象的调用相同的符号解析顺序.例:

shared.cpp:

void deleteIt(int* ptr) {
  delete ptr;
}
Run Code Online (Sandbox Code Playgroud)

main.cpp:

#include <cstdlib>
#include <new>

void* operator new(size_t size) {
  void* result = std::malloc(size);
  if (result == nullptr) {
    throw std::bad_alloc();
  }
  return result;
}

void operator delete(void* ptr) noexcept {
  std::free(ptr);
}

void deleteIt(int* ptr);

int main() {
  deleteIt(new int);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是我构建它并通过valgrind运行时会发生的事情:

$ clang++ -std=c++11 -g -O3 -flto -fuse-ld=gold -fPIC -shared shared.cpp -o libshared.so
$ clang++ -std=c++11 -g -O3 …
Run Code Online (Sandbox Code Playgroud)

c++ valgrind clang lto

5
推荐指数
1
解决办法
803
查看次数