在Java中如何在运行时找到类的实例?

在Java中如何在运行时找到类的实例?,java,reflection,Java,Reflection,假设我有一个带有注释的类,例如: @MyConfig class MyConfiguration { @MyParameter String parameter; } 如果我知道这个类存在一个实例(例如,一个实例是在另一个线程中构造的),我如何在其他地方获得对该实例的引用。我试图通过@Annotation来查找实例。您不能简单地根据对象的类型或注释来调用对象的引用,您也不应该真的这样做。其主要原因是垃圾收集——当对象超出范围时,JVM会为您清理内存;如果您可以动态创建新引用,

假设我有一个带有注释的类,例如:

@MyConfig
class MyConfiguration {

    @MyParameter
    String parameter;
}

如果我知道这个类存在一个实例(例如,一个实例是在另一个线程中构造的),我如何在其他地方获得对该实例的引用。我试图通过@Annotation来查找实例。

您不能简单地根据对象的类型或注释来调用对象的引用,您也不应该真的这样做。其主要原因是垃圾收集——当对象超出范围时,JVM会为您清理内存;如果您可以动态创建新引用,垃圾收集器将无法安全地清理任何内容,并且您将很快耗尽内存

也就是说,有很多方法可以构建功能,就像您描述的非常简单一样,这样您就可以按对象的类型查找对象

最简单(也可以说是最好的)方法是使用
映射注册您想要的实例。虽然您必须显式地添加到映射中,但实际上在代码划分方面,这对您来说要干净得多。即使将缓存行为设置为注释上的静态方法或类似的方法,将构造与缓存分离也是一个很好的实践

// somewhere accessible to both the constructing and accessing code, such as a
// public static field on the Annotation
Map<Class<? extends Annotation>,Object> annotationMap = new HashMap();

// wherever the instance is constructed
annotationMap.put(MyConfig.class, new MyConfiguration());

// wherever the instance is needed
MyConfiguration myConf = (MyConfiguration)annotationMap.get(MyConfig.class);
现在您可以确信,如果存在
MyConfiguration
实例,则可以通过其注释类型从
annotationMap
访问该实例


然而,正如我在上面所暗示的,我怀疑这两种方法都不是很好的解决方案。真正的原因是,注释根本不允许您引用实例;相反,它们的目的是让您在已有实例后了解有关实例的情况。让我问你,为什么你认为你需要通过注释来查找一个对象?有没有其他模式可以替代

我怀疑您真正想要构建的是一个-您希望您的运行时正好有一个
MyConfiguration
实例,并且希望所有代码都能轻松访问它。这方面的标准模式是:

@MyConfig
class MyConfiguration {
  private static MyConfiguration INSTANCE = null;

  public static MyConfiguration getInstance() {
    // note this is not thread-safe
    // see the above link for several thread-safe modifications
    if(INSTANCE == null) {
      INSTANCE = new MyConfiguration();
    }
    return INSTANCE;
}

这允许任何代码调用MyConfiguration.getInstance()
,并能够访问该实例。这就是说,单身通常被认为是不好的做法(尽管不如你所描述的那样)。理想情况下,您应该将配置实例传递给任何需要它的类或线程。显式地传递引用,而不是依赖半神奇的缓存或全局状态(如单例),是解决您所面临问题的“正确”方法。

您是说内存中可能存在对象的实例,您想找到它吗?类似于(不存在)
MyConfiguration obj=Runtime.getExistingInstanceOf(MyConfiguration.class)?在哪里找到?在堆里的某个地方?这是不可能的。这可能是你的答案:尤其要注意被接受答案的评论。我想这就是您正在寻找的功能。@CarCzar我现在知道如何通过注释查找类了。但问题是,如果我在堆中的某个地方(thnx到Boris)有一个类对象,那么我需要以某种方式获得对它的访问权。@JimGarrison我认为这个问题与重复的问题不同-这个问题是试图获取指向特定类型实例(碰巧是注释)的指针。
@MyConfig
class MyConfiguration {
  private static MyConfiguration INSTANCE = null;

  public static MyConfiguration getInstance() {
    // note this is not thread-safe
    // see the above link for several thread-safe modifications
    if(INSTANCE == null) {
      INSTANCE = new MyConfiguration();
    }
    return INSTANCE;
}