示例:
Integer x = 56;
正如我所理解的,只有在调用类或方法中的字段时,值才能存储在对象中。在<code>Integer</code>类的情况下,如果不实例化对象,它不应该能够调用其值字段,因为值不是静态的。这怎么可能?
语言可以并且确实为语言中内置的对象类型做任何它想要的异常。简而言之,你可以在Java做到这一点,因为Java说你可以。
具体来说,将原始值(int、Long等)转换为包装类之一(整数、Long等)称为“自动装箱”,并且就像名称所说的那样,是自动执行的。
为什么允许这样做?因为它对用户来说非常方便。除了自动拆箱,它还允许您非常接近地将包装类视为它们包含的原始值。
一些术语:你只“调用”方法,而不是变量或字段“呼叫”表示“将控制权转移到”。
在像整数这样的类中,你甚至不知道它有什么字段。你只知道它可以在一定范围内存储整数值。值只能通过调用构造函数或返回整数的静态方法之一输入到整数中。
Integer 的文档,以防您还没有看到它。请注意,没有“更改”整数值的操作;我们说它是“不可变的”。如果你想要一个不同的值,你只能创建一个新的整数。
仅当在类或方法中调用了字段时,才能将值存储在对象中。
这种说法毫无意义。我分不清这是错是对,只是……没有道理。
如果不实例化一个对象,它就不能调用它的值字段,因为值不是静态的。我只是不明白这怎么可能。
Javac看到后说:嘿,你把一个正方形的peg(int类型的常量)塞进一个圆孔(对象类型变量)-这没有意义。除了在Java语言规范中明确指出的,如果int
表达式出现在int
表达式不应该出现的地方,但是整数
表达式可以正常工作,那么“应用自动装箱”。
“应用自动装箱”的意思是:假设程序员打算写:< code>Integer.valueOf(表达式)而不是他们所写的内容。
因此:
Integer x = 56;
Integer x = Integer.valueOf(56);
是一样的。它们是如此的相同,以至于产生了相同的字节码。无论如何编写,对valueOf的调用都在类文件中。让我们测试一下:
> cat Test.java
class Test {
Integer x = 56;
}
> javac Test.java
(`javap` is part of java distributions and prints bytecode)
> javap -private -c Test
Compiled from "Test.java"
class Test {
java.lang.Integer x;
Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: bipush 56
7: invokestatic #7 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
10: putfield #13 // Field x:Ljava/lang/Integer;
13: return
}
看看这个——调用静态方法< code>Integer.valueOf,尽管< code>Integer.valueOf在我们的Test.java文件中根本没有出现。
那么,Integer是如何实现的呢。工作价值?
本质上,它的工作原理如下:
package java.lang;
public class Integer {
private static final Integer[] CACHE = generateCache();
private final int value;
public Integer(int value) {
this.value = value;
}
private static Integer[] generateCache() {
for (int i = 0; i < 256; i++) {
CACHE[i - 128] = new Integer(i);
}
}
public static Integer valueOf(int v) {
if (v >= -128 && v < 128) return CACHE[i + 128];
return new Integer(v);
}
}
换言之,Integer类预先创建了256个整数对象,从-128到127(为什么会有这些值?呃,因为sun认为这些值会经常出现,25年前缓存它们是值得的)。如果valueOf()
的值介于-128和127之间,则会得到其中一个缓存。如果你在它之外赋值of,你会得到一个新的对象。
我们也可以证明:
> cat Example.java
class Example {
public static void main(String[] args) {
Integer a = -100;
Integer b = -100;
Integer c = 200;
Integer d = 200;
System.out.println("a == b? " + (a == b));
System.out.println("c == d? " + (c == d));
System.out.println("ident-hash a: " + System.identityHashCode(a));
System.out.println("ident-hash b: " + System.identityHashCode(b));
System.out.println("ident-hash c: " + System.identityHashCode(c));
System.out.println("ident-hash d: " + System.identityHashCode(d));
}
}
> java Example.java
a == b? true
c == d? false
ident-hash a: 1880794513
ident-hash b: 1880794513
ident-hash c: 1991313236
ident-hash d: 736778932
这段代码显示了-100的整数。valueOf调用返回的是完全相同的对象(==
比较引用标识,即:它是同一个对象吗?当用于对象时,它不会比较值。a和b只是指向同一对象,而c和d指向具有相同值的不同对象)。
这就像在郊区某个地方建造的一堆相同的房子: a和b就像写着相同地址的纸片,而c和d就像写着不同地址的纸片,但是这些地址的两栋房子看起来是一样的。
我正在使用redux saga。执行分派时,会执行likePost和addPost等函数。 然后每次我使用异步存储。获取令牌的getItem。换句话说,它是重叠的 因为我必须使用jwt令牌 我需要不断传递这样的头到api。这也是重叠 这个怎么用没有冗余,或者说怎么用最方便? 这是我的密码 (saga/post.js) (佐贺/index.js)
这是我第二次使用它,也是我第一次得到非常好的帮助,所以我希望我能得到更多的帮助! 背景: 我的程序通过创建一个保存余额和其他东西的对象来测试我的 类。说明说我需要覆盖子类的“提款”和“存款”方法以跟踪交易。 我这样做了,但它不使用当前余额,而是只发送一个0。我希望能够保留新的余额,以便它实际从当前余额中提取或存款。 抱歉,如果这毫无意义,如果需要任何澄清,我将尝试以不同的方式解释。 以下是我的代码
我试图在不使用导入语句的情况下从Arrays类调用这个方法:你能告诉我怎么了吗? 非常感谢
我有一个Spring Boot应用程序,注释为。几乎所有的存储库都需要实现一些自定义逻辑,这是使用完成的。 是否有方法创建将从机制中排除的存储库?
问题内容: 我正在开发一个文档测试框架-基本上是PDF的单元测试。测试是框架定义的类的实例的(修饰)方法,并且在运行时定位并实例化这些实例,并调用这些方法以执行测试。 我的目标是减少将要编写测试的人员所关心的古怪的Python语法,因为这些人可能是也可能不是Python程序员,甚至根本不是很多程序员。因此,我希望他们能够为方法编写“ def foo():”而不是“ def foo(self):”,