考虑以下类:
class Temp {
private final int field = 5;
int sum() {
return 1 + this.field;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我编译和反编译这个类:
> javac --version
javac 11.0.5
> javac Temp.java
> javap -v Temp.class
...
int sum();
descriptor: ()I
flags: (0x0000)
Code:
stack=2, locals=1, args_size=1
0: iconst_1
1: aload_0
2: invokestatic #3 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
5: pop
6: iconst_5
7: iadd
8: ireturn
Run Code Online (Sandbox Code Playgroud)
简单来说,javac编译sum()成这样:
int sum() {
final int n = 1;
Objects.requireNonNull(this); // <---
return n + …Run Code Online (Sandbox Code Playgroud) 我在这里有一个非常棘手的案例,有泛型和方法重载.看看这个示例类:
public class Test {
public <T> void setValue(Parameter<T> parameter, T value) {
}
public <T> void setValue(Parameter<T> parameter, Field<T> value) {
}
public void test() {
// This works perfectly. <T> is bound to String
// ambiguity between setValue(.., String) and setValue(.., Field)
// is impossible as String and Field are incompatible
Parameter<String> p1 = getP1();
Field<String> f1 = getF1();
setValue(p1, f1);
// This causes issues. <T> is bound to Object
// ambiguity between setValue(.., Object) and setValue(.., Field) …Run Code Online (Sandbox Code Playgroud) 当我.class参与其中package并尝试从cmd运行它时,我不断收到错误.
这是使用后使用的代码,javac然后是java:
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
Run Code Online (Sandbox Code Playgroud)
然后代码不起作用:
package com;
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
Run Code Online (Sandbox Code Playgroud)
尝试通过命令运行程序后给我这个错误java HelloWorld::
Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld (wrong nam
e: com/HelloWorld)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown …Run Code Online (Sandbox Code Playgroud) 我阅读了Sun文档和Stack Overflow上的很多帖子,但我仍然对Java编译器选项-cp和Java之间的差异感到困惑-sourcepath.
假设我有这个目录结构:
c:\Java\project1\src (where the Java source files are)
c:\Java\project1\bin (where the Java class files will be or already are)
Run Code Online (Sandbox Code Playgroud)
我们还说我MainClass.java在包中有一个源文件com.mypackage,并且源文件夹中的目录结构正常.
我在project1目录中并运行:
javac -d bin -sourcepath src src/com/mypackage/MainClass.java
Run Code Online (Sandbox Code Playgroud)
要么
javac -d bin -classpath src src/com/mypackage/MainClass.java
Run Code Online (Sandbox Code Playgroud)
我得到了同样的结果.在详细模式下,源文件的搜索路径src在两种情况下都是如此.
如果有人能帮助我弄清楚这些选项的具体细节,那就太好了.
Maven编译器插件文档说明:
Compiler Plugin用于编译项目的源代码.从3.0开始,默认编译器是javax.tools.JavaCompiler(如果您使用的是java 1.6)并且用于编译Java源代码.如果要使用javac强制插件,则必须配置插件选项
forceJavacCompilerUse
事实上,当forceJavacCompilerUse我们的构建中没有指定时,会出现一些构建错误,例如当代码引用com.sun.包时(遗产,我们知道这是一个坏主意......)
这两种编译模式与maven有什么区别?是否应该知道任何产出差异?
如果你看一下字节码
Consumer<String> println = System.out::println;
Run Code Online (Sandbox Code Playgroud)
Java 8更新121生成的字节代码是
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
DUP
INVOKEVIRTUAL java/lang/Object.getClass ()Ljava/lang/Class;
POP
INVOKEDYNAMIC accept(Ljava/io/PrintStream;)Ljava/util/function/Consumer; [
// handle kind 0x6 : INVOKESTATIC
java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
// arguments:
(Ljava/lang/Object;)V,
// handle kind 0x5 : INVOKEVIRTUAL
java/io/PrintStream.println(Ljava/lang/String;)V,
(Ljava/lang/String;)V
]
ASTORE 1
Run Code Online (Sandbox Code Playgroud)
getClass()正在调用该方法System.out,结果被忽略.
这是间接空引用检查吗?
当然,如果你跑
PrintStream out = null;
Consumer<String> println = out::println;
Run Code Online (Sandbox Code Playgroud)
这会触发NullPointerException.
我有一个Java文件,当我编译时,在java编译器(javac)退出之后,我将只能在控制台上看到前100个错误.我怎样才能在控制台上看到所有编译错误?在此先感谢 - opensid
我最近在C中编写了很多代码,现在正在转向Java.我目前正在实现一个大型数据结构,并且想知道在调用Java编译器时是否可以打开任何优化标志以提高gcc中的性能.
我习惯了:
gcc -O3 -NDEBUG MyProgram.c
Run Code Online (Sandbox Code Playgroud)
有一个类似的命令javac吗?
我正在使用JDK并且正在运行Ubuntu 10.04.
我买了一台新电脑java,我想设定,让我可以使用javac,并java通过命令行.
我在网上搜索过,但所有的指南都是以前的版本,我不想搞乱我不理解的东西.
我正在编写一个makefile,它编译一个.java不同目录中的文件,然后我想运行它,而不更改目录.我想做一些事情:
$(SQM_JAVA_TOOL_DONE) : $(SQM_JAVA_TOOL)
$(shell cd /home_dir)
javac myjavafile.java
java myjavafile
Run Code Online (Sandbox Code Playgroud)
Java文件所在的位置/home/myjavafile.java,并且未运行makefile /home.
我怎样才能做到这一点?
java ×10
javac ×10
java-8 ×2
bytecode ×1
class ×1
cmd ×1
command-line ×1
ecj ×1
eclipse ×1
generics ×1
java-11 ×1
jvm ×1
lambda ×1
maven ×1
optimization ×1
overloading ×1
package ×1
path ×1
windows-10 ×1