首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ArchUnit:未检测到泛型的循环依赖关系

ArchUnit:未检测到泛型的循环依赖关系
EN

Stack Overflow用户
提问于 2020-11-02 07:57:52
回答 2查看 481关注 0票数 0

ArchUnit 0.14.1没有检测用作泛型字段参数的类型的循环依赖关系。这是ArchUnit中的限制还是我做错了什么?例如:

代码语言:javascript
复制
package com.test.a;
import com.test.b.B;

public class A {
    protected B b;
}
代码语言:javascript
复制
package com.test.b;
import java.util.Optional;
import com.test.a.A;

public class B {
    protected Optional<A> a; // not detected by archunit
    // protected A a2; // detected by archunit
}
代码语言:javascript
复制
@AnalyzeClasses(packages = "com.test")
public class ArchitecturalChecks {

    @ArchTest
    public void testNoCycles(JavaClasses importedClasses) {
        SlicesRuleDefinition.slices().matching("com.test.(*)..").should().beFreeOfCycles().check(importedClasses);
    }

    @ArchTest
    public void testPackageStructure(JavaClasses importedClasses) {
        // @formatter:off
        Architectures.layeredArchitecture()
            .layer("A").definedBy("com.test.a..")
            .layer("B").definedBy("com.test.b..")
            .whereLayer("A").mayNotBeAccessedByAnyLayer()
            .whereLayer("B").mayOnlyBeAccessedByLayers("A")
            .check(importedClasses);
        // @formatter:on
    }

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-13 14:15:52

ArchUnit目前(截至版本 0.16.0)很遗憾还没有全力支持泛型,但这一点正在进行中。(例如,与以前的版本不同,ArchUnit 0.16.0已经检测到了class B extends ArrayList<A>的依赖性。)

我确信ArchUnit的某些未来版本将通过字段的泛型类型参数检测依赖项,因为这些信息实际上存在于字节代码中,请参见javap -v B.class

代码语言:javascript
复制
public class com.test.b.B
  minor version: 0
  major version: 55
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
  this_class: #2                          // com/test/b/B
  super_class: #3                         // java/lang/Object
  interfaces: 0, fields: 1, methods: 1, attributes: 1
Constant pool:
   #1 = Methodref          #3.#14         // java/lang/Object."<init>":()V
   #2 = Class              #15            // com/test/b/B
   #3 = Class              #16            // java/lang/Object
   #4 = Utf8               a
   #5 = Utf8               Ljava/util/Optional;                  // <- erased type of a
   #6 = Utf8               Signature
   #7 = Utf8               Ljava/util/Optional<Lcom/test/a/A;>;  // <- generic type of a
   #8 = Utf8               <init>
   #9 = Utf8               ()V
  #10 = Utf8               Code
  #11 = Utf8               LineNumberTable
  #12 = Utf8               SourceFile
  #13 = Utf8               B.java
  #14 = NameAndType        #8:#9          // "<init>":()V
  #15 = Utf8               com/test/b/B
  #16 = Utf8               java/lang/Object
{
  protected java.util.Optional<com.test.a.A> a;
    descriptor: Ljava/util/Optional;
    flags: (0x0004) ACC_PROTECTED
    Signature: #7                           // Ljava/util/Optional<Lcom/test/a/A;>;

  // ...
票数 0
EN

Stack Overflow用户

发布于 2020-12-15 12:33:28

ArchUnit通过分析给定的Java字节码来完成它的工作。

泛型是类型擦除的主题之一,因此在被检查的字节码中不存在类型信息,在该字节码中,您的字段将被表示为Optional<Object> a,因此不会检测到循环。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64641710

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档