gpt4 book ai didi

方法中的Java本地内部类,JVM如何处理它?

转载 作者:搜寻专家 更新时间:2023-11-01 01:46:24 26 4
gpt4 key购买 nike

如果您查看下面的方法,您将在方法中看到一个已声明的本地类。原因是,例如 styleIt0 方法被多次使用并且仅在此方法中使用。它仅与此方法有关。

将其分解为一个私有(private)方法并不能很清楚地知道它的用途和作用,仅通过查看它就可以了。我发现大块代码不可读,并且经常想用小方法分解,尽管它们只与一种方法相关。

对一个类中的多个方法执行此操作将使每个私有(private)方法的用途和用途变得非常不清楚,并且与可能在多个之间共享的其他私有(private)方法相比,它仅由单个方法使用方法。

这就是为什么我有时更喜欢在一个方法中声明其他方法。允许以“标准”方式在方法中声明方法会很棒,但我认为在 Java 6 之前唯一可能的方法是在方法的局部内部类中声明方法,如下所示。

我的问题是:

这种用法是否存在任何性能问题?这样一个声明的类和重复调用具有本地内部类的方法的内存占用是多少? JVM 会在编译时编译这个类一次,还是以其他方式处理它?

其他想法:
本地内部类不能声明为静态的,它们的方法和属性也不能是静态的。我想知道为什么!?

现在每次调用该方法时我都被迫创建一个新实例。在本地内部类中使用静态方法会很棒,但我认为没有充分的理由说明为什么这不可能?内部方法会更好!

一些 可能会争辩说这种编码方式没有用,很丑陋,或者可以在其他地方声明此类。请不要在那个方向劫持线程。不管有些人怎么说,我碰巧发现内部方法很有用。我的主要兴趣与 Java 语言中这种用法的性能问题有关。

谢谢(下面的代码)

private void addBottomTable(Slide slide, User user) {
class Styler {

public void styleIt0(RichTextRun rt) {
rt.setFontName(font);
rt.setFontSize(12);
rt.setBold(true);
}

public void styleIt1(RichTextRun rt) {
rt.setFontName(font);
rt.setFontSize(10);
rt.setBold(true);
}

public void styleTable(Table table) {
// Style the table
double numberOfCakes = width / PADDING;
int firstColumnWidth = (int) ((3 / 12d) * numberOfCakes * PADDING); // Take 3/12 of the cakes and calculate the width
table.setColumnWidth(0, firstColumnWidth);

table.setColumnWidth(1, width - firstColumnWidth - PADDING * 2); // Minus padding because we use that one for moveTo at the end, and we do want padding
// at the end
Line border = table.createBorder();
border.setLineStyle(Line.PEN_PS_DASH);
border.setLineColor(Color.black);
border.setLineWidth(1.0);
table.setAllBorders(border);
}

}
Styler styler = new Styler();
EmployeeCV employeeCV = user.getEmployeeCv();
Table table = new Table(3, 2);
styler.styleTable(table);

// == Cells ==
// Row 0 = Specific strengths
TextRun textRun = table.getCell(0, 0).getTextRun();
RichTextRun rt = textRun.getRichTextRuns()[0];
rt.setText("Specific strengths: ");
styler.styleIt0(rt);

// Content column
textRun = table.getCell(0, 1).getTextRun();
rt = textRun.getRichTextRuns()[0];

StringBuffer s = new StringBuffer();
List<LeadershipTopStrengths> strengths = employeeCV.getTopStrengthsList();
int i = 0;
while (i < strengths.size()) {

LeadershipTopStrengths strength = strengths.get(i);

if ( strength != null ) {
s.append(safeEnumItemDescription(strength));

// Add newline but not on the last one
if (i < (strengths.size() - 1) ) {
s.append(SIMPLE_NEWLINE);
}

rt.setText(s.toString());
styler.styleIt1(rt);
}

i++;
}

// Row 1 = Mobility
textRun = table.getCell(1, 0).getTextRun();
rt = textRun.getRichTextRuns()[0];
rt.setText("Mobility: ");
styler.styleIt0(rt);

// Content column
textRun = table.getCell(1, 1).getTextRun();
rt = textRun.getRichTextRuns()[0];

s = new StringBuffer();
List<InternationalMobility> mobilities = employeeCV.getInternationalMobilityList();
i = 0;
while (i < mobilities.size()) {

InternationalMobility mobility = mobilities.get(i);
if(mobility != null){
s.append(safeEnumItemDescription(mobility));

// Add newline but not on the last one
if (i < (mobilities.size() - 1) ) {
s.append(SIMPLE_NEWLINE);
}

rt.setText(s.toString());
styler.styleIt1(rt);

}
i++;
}

// Row 2 = Additional
textRun = table.getCell(2, 0).getTextRun();
rt = textRun.getRichTextRuns()[0];
rt.setText("Additional information: ");
styler.styleIt0(rt);

// Content column
// TableCell cell = table.getCell(2, 1);


slide.addShape(table);
table.moveTo(PADDING, height / 2 + PADDING * 2); // MoveTo must come after
}

最佳答案

JVM 不编译类,javac 编译类。

而且,事实上,JVM 对任何形式的内部类基本上一无所知——它们被编译为单独的类,并且 JVM 以这种方式对待它们。所有内部类功能都是通过编译器生成的 swizzles 完成的(除非这在 Java 5 后发生了变化)。 (而且我一直怀疑因此存在几个安全漏洞,但从来没有费心去寻找它们。)

如果您在多个方法中包含完全相同的类,我不知道编译器是否以某种方式发现它们是相同的,只生成一个副本,或者它是否生成多个副本。一些简单的测试会告诉您。

内部方法无疑可以(相对容易地)用 Java 实现,但设计者选择在 Java 1 中避免这种复杂性(特别是考虑到他们的模型是 C),然后将所有精力投入到内部类中。没有真正的原因,除了它没有成为任何人的宠物想法,我怀疑。

[其实不实现内部类是有原因的,但不是不可逾越的原因。如果没有“显示”和一些额外的操作码,原始的 Java 执行堆栈模型将无法支持它,而且,自最初的设计以来,Java 设计人员一直非常不愿意向 JVM 添加甚至明显需要的新功能(如没有 JVM mod 的内部类的实现)。 (尽管奇怪的是,他们在 5 中实现了高度不兼容和普遍(并且可能是不必要的)验证更改。)]

关于方法中的Java本地内部类,JVM如何处理它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8941601/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com