小编Cod*_*ete的帖子

箭头(->)运算符的优先级/优先级最低,还是分配/组合分配的优先级最低?

JLS

最低优先级操作者是lambda表达式的箭头( - >) 随后由赋值运算符。

遵循哪个方向(增加优先级,减少优先级)?-“跟随”是指分配的优先级较高还是较低(相对于箭头运算符)?我猜想,这是因为“最低”(箭头)表示绝对最低。

据我了解,箭头(->)应该位于此Princeton运算符优先级表的最底部(在所有赋值运算符的下方),因此箭头(->)的优先级为0(零)(根据该表)。

我的理解正确吗?

ExamTray似乎说箭头优先级至少与分配相同。此外,还阐明了箭头的关联性是Left-> To-> Right(与分配不同)。我没有找到JLS的箭头关联性报价。

我一直认为分配优先级原则上最低。

java specifications operator-precedence language-lawyer java-8

17
推荐指数
2
解决办法
564
查看次数

JLS中f1()+ f2()* f3()表达式的执行顺序和运算符优先级

给定一个f1() + f2()*f3()带有3个方法调用的表达式,java首先计算加法运算(的操作数):

int result = f1() + f2()*f3();

f1 working
f2 working
f3 working
Run Code Online (Sandbox Code Playgroud)

我(错误地)期望f2()首先被呼叫,然后被呼叫f3(),最后被呼叫f1()。因为乘法应在加法之前求值。

所以,我在这里不了解JLS-我想念什么?

15.7.3。评估尊重括号和优先权

Java编程语言遵守 由括号显式表示由运算符优先级隐式表示的评估顺序

在此示例中,如何精确地遵守运算符优先级?

JLS在15.7.5中提到了一些例外其他表达式(方法调用表达式(§15.12.4),方法引用表达式(§15.13.3))的评估顺序,但是我不能将这些异常中的任何一个应用于我的示例。

我知道JLS保证二进制运算的操作数从左到右求值。但是在我的示例中,为了了解方法调用顺序,有必要了解首先考虑哪个操作(及其两个操作数!)。我在这里错了-为什么?

更多示例:

int result = f1() + f2()*f3() + f4() + f5()*f6() + (f7()+f8());
Run Code Online (Sandbox Code Playgroud)

自豪地生产:

f1 working
f2 working
f3 working
f4 working …
Run Code Online (Sandbox Code Playgroud)

java evaluation expression-evaluation operator-precedence jls

10
推荐指数
2
解决办法
297
查看次数

为什么ArrayList add()和add(int index,E)复杂度是分摊的常量时间?为什么O(1)for add(),O(n)for add(int index,E)?

为什么ArrayList add()和add(int index,E)复杂度是分摊的常量时间?

为什么O(1)用于单个add()操作,O(n)用于单个add(int index,E)操作,O(n)用于添加n个元素(n add操作)使用任何(任何)add方法?假设我们使用add(int index,E)很少添加到数组端?

数组(和ArrayList)的一个操作复杂性不是已经有n个元素:

  1. add() - O(1)?
  2. add(int index,E) - O(n)?

如果我们进行一百万次插入,1和2的平均值不能为O(1),对吗?

为什么甲骨文说

添加操作以分摊的常量时间运行,即添加n个元素需要O(n)时间.

我认为add()的复杂度为O(1),add(int index,E)的复杂度为O(n).

这是否意味着"n个操作的整体复杂性"(复杂度O(1)的每个操作)可以说是n*O(1)= O(n).我错过了什么?

也许对于Oracle"添加操作"总是意味着只有add()?而add(int,E)是"插入操作"?然后完全清楚!

我有一个猜测,它与渐近分析摊销分析之间的差异有关,但我无法把握它到最后.

什么是算法的摊销分析?

为什么数组插入的时间复杂度是O(n)而不是O(n + 1)?

对于插入未排序的动态数组,更适合使用Amortized O(1)vs O(n)?(不太清楚)

将O添加到不同的例程时

java arrays arraylist time-complexity

9
推荐指数
1
解决办法
1万
查看次数

什么是 JUnit5 平台启动器?

JUnit 5 是模块化的。

我了解一切都基于平台模块( junit-platform-engine-1.3.2.jar):

Jupiter 模块API + 引擎部件junit-jupiter-engine-5.3.2.jar+ junit-jupiter-api-5.3.2.jar)和

Vitage 模块API + 引擎部分junit-vintage-engine-5.3.2.jar+junit-4.12.jarhamcrest-core-1.3.jar)都使用平台模块作为基本模块。

但是什么是平台启动器,什么时候需要它?

我何时以及为什么需要它以及如何将其添加到pom.xml

朱尼特 (图片来自此链接

将 Jupiter(仅用于 JUnit 5 测试)和 Vintage(用于 Junit4/Junit3 兼容性 - 从 JUnit5 运行遗留 JUnit4 测试)到 pom.xml 是这样的(仅供将来参考):

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.3.2</version>
    <scope>test</scope>
</dependency>

<!-- Vintage Module to run JUnit4 from JUnit 5 -->
<dependency>
    <groupId>org.junit.vintage</groupId>
    <artifactId>junit-vintage-engine</artifactId>
    <version>5.3.2</version>
    <scope>test</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)

maven junit5

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

为什么int p =(p = 1)+ p; 字段定义中失败,但是方法内可以吗?

class Test{

    int p = (p=1) + p;   // ERR "Cannot reference a field before it is defined"
    int q = (q=1) + this.q; //fine!

    void f() {
        int t = (t=1) + t; // fine!
    }       
}
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,我了解:执行赋值(或后续加法?)时,p被视为未声明。

但是,为什么一个方法内有不同呢?OK t不会被视为未初始化,因为(t = 1)在加法之前执行。好的,t不是一个字段,但是目前还没有声明!

我能以某种方式理解吗?还是我会记住这种差异?

也许这也与以下内容有关:

    static int x = Test.x + (x=1) + Test.x; // produces 2

    void f() {
       int y = y + (y=1) + y;  // ERR  local variable y may not have been initialized
   }
Run Code Online (Sandbox Code Playgroud)

为什么是2?首先以某种方式评估(x …

java

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

代码根据JLS"模糊"的例子(6.4.2.模糊),特别是这个"局部变量或类型可以模糊包"

你能举几个模糊的例子(代码片段)吗?

我读过JLS,但我不明白这个概念.JLS没有提供代码示例.

隐藏在Base和Derived类的字段之间.

阴影位于字段和局部变量之间.

模糊 - 在什么(?)和什么(?)之间

SIDELINE:有趣的是,JLS表示如果隐藏来自父类的相应字段,则不会继承:

阴影与隐藏不同(§8.3,§8.4.8.2,§8.5,§9.3,§9.5),它仅适用于否则将被继承但不是因为子类中的声明的成员.阴影也不同于模糊(第6.4.2节).

我也知道类名,方法名和字段名都在不同的名称空间中:

// no problem/conflict with all three x's
class x {
    void x() { System.out.println("all fine"); }
    int x = 7; 
}
Run Code Online (Sandbox Code Playgroud)

例子:

最后找到了一个例子,有些解释什么声称是模糊(它会导致编译错误):

class C {
    void m() {
        String System = "";
        // Line below won't compile: java.lang.System is obscured 
        // by the local variable  String System = ""
        System.out.println("Hello World");  // error: out can't be resolved …
Run Code Online (Sandbox Code Playgroud)

java

7
推荐指数
2
解决办法
97
查看次数

当使用非泛型方法覆盖泛型方法时,为什么subsignature和unchecked规则在返回类型上以这种方式工作?

public class Base {

     <T> List<? extends Number>  f1()  {return null;}
     List<? extends Number>      f2()  {return null;}
     <T extends Number> List<T>  f3()  {return null; }
}

class Derived extends Base {

     List<String> f1() {return null;}   // compiles fine !!!
     List<String> f3() {return null; }  // compiles fine !!!

    // compile ERR: return type is incompatible with Base.f2()
     List<String> f2() {return null;}   
}
Run Code Online (Sandbox Code Playgroud)

为什么在Derived类中定义重写方法f1()和f3()不会产生编译错误,比如Derived类中的重写f2()方法的定义(它给出编译错误"返回类型与Base.f2()不兼容")?

JLS中的子签名覆盖规则允许覆盖方法(在Derived类中)是非泛型的,而重写方法(在Base类中)是通用的.

未经检查的覆盖规则允许在子类List<String>而不是List<T>在Base类中生成返回类型.

但我无法解释下面的行为差异,我不明白为什么fin()和f3()覆盖Derived类中的定义成功编译(在Eclipse,SE8上),忽略了f3()的有界类型参数所施加的限制f1()的有界通配符!

PS我的猜测 - 在衍生编译器中的f1()和f3()中将两个方法视为仅返回"原始"列表 - 编译器首先进行擦除(此时仅在Derived!中),然后在Derived中比较这些已擦除的方法Base中未删除(迄今为止)的方法.现在未经检查的覆盖规则是正常的(并且不需要检查边界 - …

java generics inheritance

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

为什么静态和默认接口方法不能同步但可以是strictfp?

为什么静态和默认接口方法不能同步?

人们说synchronized是一个实现细节.那么,strictfp也是一个实现细节,但这并不妨碍在静态和默认接口方法上允许strictfp.

如果实现接口的类没有覆盖默认方法,则继承默认方法并使其已经同步可能非常方便.

我猜测synchronized(以及strictfp)不是继承的(我在这里吗?),但这并不能解释为什么strictfp也允许静态和默认接口方法.

java interface

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

编译器从不检查转换为泛型类型(T)?

static <T> void f1(Base arg1, T arg2) {
    T loc = (T) arg1; // why Derived is "kind of cast" to String?
    System.out.println(loc.getClass().getName()); // would print: Derived
}

f1(new Derived(), "sdf");  // T is String - inferred from arg2

class Base { }

class Derived extends Base { }
Run Code Online (Sandbox Code Playgroud)

我的想法是正确的:写作演员(T)意味着"编译器不能也不会检查这个演员".在编译时编译器不知道arg2会是什么(并且它可能是任何东西),因此编译器不能排除强制转换可以工作并且必须信任程序员.因此,在编译时永远不会检查此强制转换.在运行时,局部var声明看起来像Object loc = arg1;(在类型擦除之后).所以一切正常,因为编译器从不关心这个(T)演员?

PS:我的研究:这个,这个.这也很有意思("将原语转换为通用":( T)true)我的问题更明确地指出问题,问题还在于编译器是否检查了演员(T)并且没有分心有问题的代码示例.

java generics casting

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

为什么在从默认接口方法调用静态接口方法时不能使用它?

为什么在接口中从默认接口方法调用静态接口方法我不能使用this.staticInterfaceMethod()而在常规类中从实例方法调用静态类方法是完全有效的 this.staticClassMethod()(虽然它是不好的风格)?

同时,this在接口的默认方法中使用是完全有效的 - 我可以合法地执行以下操作:

interface I {   
    int MY_CONST = 7;   
    static void st_f() {}       
    default void f1() {}

    default void f_demo() {
        this.f1();                  // fine!
        int locvar = this.MY_CONST; // also fine! 

        this.st_f(); // c.ERR:  static method of interface I can only be accessed as I.st_f 
    }
}
Run Code Online (Sandbox Code Playgroud)

java interface

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