在java中,说我有以下内容
==fileA.java==
class A
{
public static final int SIZE = 100;
}
Run Code Online (Sandbox Code Playgroud)
然后在另一个文件中我使用此值
==fileB.java==
import A;
class b
{
Object[] temp = new Object[A.SIZE];
}
Run Code Online (Sandbox Code Playgroud)
当这个被编译时会SIZE被替换为值100,所以如果我要在路上替换FileA.jar而不是FileB.jar,对象数组将获得新值或者它是否已被硬编码为100,因为那是它最初建成时的价值?
谢谢,
斯蒂芬妮
好哇!
这段代码工作了一段时间,然后我决定添加一个默认颜色,它停止工作.我收到以下错误:
1 error found:
File: Status.java [line: 20]
Error: Status.java:20: illegal reference to static field from initializer
Run Code Online (Sandbox Code Playgroud)
在编译时使用以下代码.
import java.awt.Color;
enum Status
{
OFF ("Off"),
TRAINING ("Training", new Color(255, 191, 128)),
BEGINNER ("Beginner", new Color(128, 255, 138)),
INTERMEDIATE ("Intermediate", new Color(128, 212, 255)),
ADVANCED ("Advanced", new Color(255, 128, 128));
public final String name;
public final Color color;
public static final Color defaultColor = Color.WHITE;
Status(String name)
{
this(name, defaultColor);
}
Status(String name, Color color)
{
this.name = name;
this.color …Run Code Online (Sandbox Code Playgroud) 拿这两个Java类:
class User {
final Inventory inventory;
User (Inventory inv) {
inventory = inv;
}
}
class Inventory {
final User owner;
Inventory (User own) {
owner = own;
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法没有使用反射*来解决这个问题?我实际上并不指望它是,但它可以不会受到质疑.
更新:因为在字节码构造中有两个步骤(1.分配对象,2.调用构造函数**)这可能是(ab)用来做手写字节码或自定义编译器吗?我正在谈论首先对两个对象执行步骤1,然后使用步骤1中的参考执行步骤2.当然,类似的东西会相当麻烦,这部分问题是学术性的.
(*因为反射可能会给安全管理员带来麻烦)
(**说我的知识有限)
为什么不声明一个数组最终使它在Java中不可变?不宣称最终意味着它无法改变?
从与不可变数组相关的问题中可以清楚地看出,声明一个数组final并不会使它不可更改.
以下是可能的.
final int[] array = new int[] {0, 1, 2, 3};
array[0] = 42;
Run Code Online (Sandbox Code Playgroud)
我的问题是:那么在这里宣布决赛的功能是什么?
我与有效的java有一点冲突.一方面,它强烈鼓励使用最终修饰符.它还鼓励使用foreach循环.
但是我没有在任何地方看到任何代码,代码如下:
for (final element e : list) {
// do whatever.
}
Run Code Online (Sandbox Code Playgroud)
如果预计元素不会改变,那么使用final似乎是好的.为什么不那么常见?
这可能是一个愚蠢的问题,但无论如何我都会冒这个问题.
通常我需要创建一个final变量以供其他地方使用,并且需要根据某些条件设置该变量的值.这就是我通常这样做的方式:
String notFinalVersion = null;
if (someThing == 1) {
notFinalVersion = "The value was 1.";
} else {
notFinalVersion = "The value is not 1.";
}
final String finalVersion = notFinalVersion;
Run Code Online (Sandbox Code Playgroud)
然后我可以finalVersion在需要的地方使用变量.但是,这似乎有些不对劲.有一个更好的方法吗?
编辑:通过"更好",我的意思是我正在寻找一种方法来定义最终变量,不需要我创建一个额外的变量.我知道创建一个额外的变量是低效的,而不是一个好的做法,而且我很肯定必须有一种方法可以在没有额外步骤的情况下完成需要完成的工作.
我收到了一个答案,我已将其标记为已接受.正如我在评论中所述,我最初尝试过提供的解决方案,但收到了Eclipse的错误.我必须在第一次输入错误,或者Eclipse有一些"打嗝".
我接受有许多方法可以做某事,一个人接受的最佳方式不是别人会考虑的.但是,这里包含的所有答案都很明确,而且我觉得,解决了我的问题.
我正在尝试在超类中实现一个方法,该方法应该可以在子类中使用,但不能更改.考虑一下:
export abstract class BaseClass {
universalBehavior(): void {
doStuff(); // Do some universal stuff the same way in all sub classes
specializedBehavior(); // Delegate specialized stuff to sub classes
}
protected abstract specializedBehavior(): void;
}
Run Code Online (Sandbox Code Playgroud)
我的意图是BaseClass的任何子类不仅可以省略实现universalBehavior(),甚至不允许提供实现.这在TypeScript中是不是可能?当我省略子类中的实现时,Intellisense会抱怨.我能做的最好的就是:
export class SubClass extends BaseClass {
universalBehavior(): void {
super.universalBehavior();
}
specializedBehavior(): void {
// sub class' implementation
}
}
Run Code Online (Sandbox Code Playgroud)
显然这是有问题的,因为我必须确保没有子类实现universalBehavior()除了调用之外的任何东西super.universalBehavior().
我在覆盖Enum中的equals方法时遇到问题,使其与其他类兼容.Enum实现了一个接口,其思路是可以测试此接口的所有实现是否相等,无论其类型如何.例如:
public interface Group {
public Point[] getCoordinates();
}
public enum BasicGroups implements Group {
a,b,c; // simplified, they actually have constructors
// + fields and methods
}
public class OtherGroup implements Group {
// fields and methods
}
Run Code Online (Sandbox Code Playgroud)
如果a BasicGroup和a OtherGroup具有相同的坐标(按任意顺序),则equals方法应返回true.
执行时没问题,myOtherGroup.equals(BasicGroup.a)但由于Enums中的equals方法是最终的,我无法覆盖它们.
有办法解决这个问题吗?就像在另一个BasicGroup上测试时一样,使用默认的equals方法(引用相等),并且在测试其他类时使用我自己的实现.我该如何确保java不使用错误的BasicGroup.a.equals(myOtherGroup)?
在后续代码中,我遇到了一个我以前不知道的行为.
考虑第一种情况:
public static void main(String[] args) {
final String str = null;
System.out.println(str.length()); // Compiler Warning: NullPointerAccess
}
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,编译器显示我对下面的警告str是空 - 空指针访问:变量str只能是空在这个位置.
现在,当我将该变量移动一个初始化为null的静态final字段时:
class Demo {
static final String str = null;
public static void main(String[] args) {
System.out.println(str.length()); // No Compiler Warning
}
}
Run Code Online (Sandbox Code Playgroud)
现在,编译器没有显示任何警告.AFAIK,编译器应该知道,str在代码的任何一点,它都是最终的,不会改变它的值.鉴于它确实如此null,肯定会在NullPointerException以后产生,它确实会产生.
虽然编译器在第一种情况下成功警告我,为什么它在第二种情况下无法识别.为什么这种行为改变?行为是相同的,如果我将static字段更改为instance字段,并使用实例访问它Demo.
我认为这种行为可能已在JLS中指定,因此我浏览了主题定义分配,但没有找到与此问题相关的任何内容.任何人都可以解释行为的变化吗?如果可能的话,我正在寻找一些与JLS有关的强点吗?
除此之外,为什么编译器首先只向我显示警告,因为我认为出于与上述相同的原因,方法调用肯定会在运行时抛出NPE,因为字段无法更改?为什么不向我显示编译器错误?我是否期望编译器太多,因为它似乎很明显,运行时结果str.length()不能超过 …
如果实例变量设置为final,则其值不能更改为
public class Final {
private final int b;
Final(int b) {
this.b = b;
}
int getFinal() {
return b = 8; // COMPILE TIME ERROR
}
}
Run Code Online (Sandbox Code Playgroud)
在代码的某处我看到实例类变量 HashMap被 声明为final
private final Map<String, Object> cacheMap = new HashMap<String, Object>();
Run Code Online (Sandbox Code Playgroud)
我不明白为什么这样宣布?通常在这种情况下它被声明.这是否意味着如果我放入哈希映射然后我无法更改其值?
编辑:
如果声明为final的cacheMap作为参数传递给另一个类,那么如果我更改其引用,则不会显示final的错误.为什么会这样?
class CacheDTO {
private Map conditionMap;
public Map getConditionMap() {
return conditionMap;
}
public void setConditionMap(Map conditionMap) {
this.conditionMap = conditionMap;
}
}
Run Code Online (Sandbox Code Playgroud)
然后
private final Map<String, Object> cacheMap = new HashMap<String, Object>();
CacheDTO cc = …Run Code Online (Sandbox Code Playgroud) final ×10
java ×9
enums ×2
immutability ×2
static ×2
compilation ×1
equals ×1
inheritance ×1
overriding ×1
reflection ×1
sealed ×1
typescript ×1
variables ×1