62,614
社区成员
发帖
与我相关
我的任务
分享
package com.test;
public class People {
public static String getClassName() {
return new Object() {
private String getName() {
String className = getClass().getName();
return className.substring(0, className.indexOf("$"));
}
}.getName();
}
}
package com.test;
public class Teacher extends People{
}
import com.test.Teacher;
public class Test {
public static void main(String[] args) throws Exception {
System.out.println(Teacher.getClassName());
}
}
Compiled from "TestMain.java"
public class pkgname.staticinherit2.TestMain extends java.lang.Object
。。。。。。
const #16 = Method #17.#19; // pkgname/staticinherit2/Teacher.getClassName:()Ljava/lang/String;
const #17 = class #18; // pkgname/staticinherit2/Teacher
const #18 = Asciz pkgname/staticinherit2/Teacher;
const #19 = NameAndType #20:#21;// getClassName:()Ljava/lang/String;
const #20 = Asciz getClassName;
const #21 = Asciz ()Ljava/lang/String;;
。。。。。。
public static void main(java.lang.String[]);
Code:
Stack=2, Locals=2, Args_size=1
0: invokestatic #16; //Method pkgname/staticinherit2/Teacher.getClassName:()Ljava/lang/String;
3: astore_1
4: getstatic #22; //Field java/lang/System.out:Ljava/io/PrintStream;
7: aload_1
8: invokevirtual #28; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
11: return
在Teacher,class里你会看到类似
Compiled from "TestMain.java"
public class pkgname.staticinherit2.TestMain extends java.lang.Object
SourceFile: "TestMain.java"
minor version: 0
major version: 46
Constant pool:
const #1 = class #2; // pkgname/staticinherit2/TestMain
const #2 = Asciz pkgname/staticinherit2/TestMain;
const #3 = class #4; // java/lang/Object
const #4 = Asciz java/lang/Object;
const #5 = Asciz <init>;
const #6 = Asciz ()V;
const #7 = Asciz Code;
const #8 = Method #3.#9; // java/lang/Object."<init>":()V
const #9 = NameAndType #5:#6;// "<init>":()V
const #10 = Asciz LineNumberTable;
const #11 = Asciz LocalVariableTable;
const #12 = Asciz this;
const #13 = Asciz Lpkgname/staticinherit2/TestMain;;
const #14 = Asciz main;
const #15 = Asciz ([Ljava/lang/String;)V;
const #16 = Method #17.#19; // pkgname/staticinherit2/Teacher.getClassName:()Ljava/lang/String;
const #17 = class #18; // pkgname/staticinherit2/Teacher
const #18 = Asciz pkgname/staticinherit2/Teacher;
const #19 = NameAndType #20:#21;// getClassName:()Ljava/lang/String;
const #20 = Asciz getClassName;
const #21 = Asciz ()Ljava/lang/String;;
const #22 = Field #23.#25; // java/lang/System.out:Ljava/io/PrintStream;
const #23 = class #24; // java/lang/System
const #24 = Asciz java/lang/System;
const #25 = NameAndType #26:#27;// out:Ljava/io/PrintStream;
const #26 = Asciz out;
const #27 = Asciz Ljava/io/PrintStream;;
const #28 = Method #29.#31; // java/io/PrintStream.println:(Ljava/lang/String;)V
const #29 = class #30; // java/io/PrintStream
const #30 = Asciz java/io/PrintStream;
const #31 = NameAndType #32:#33;// println:(Ljava/lang/String;)V
const #32 = Asciz println;
const #33 = Asciz (Ljava/lang/String;)V;
const #34 = Asciz args;
const #35 = Asciz [Ljava/lang/String;;
const #36 = Asciz result;
const #37 = Asciz Ljava/lang/String;;
const #38 = Asciz SourceFile;
const #39 = Asciz TestMain.java;
{
public pkgname.staticinherit2.TestMain();
Code:
Stack=1, Locals=1, Args_size=1
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 4: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lpkgname/staticinherit2/TestMain;
public static void main(java.lang.String[]);
Code:
Stack=2, Locals=2, Args_size=1
0: invokestatic #16; //Method pkgname/staticinherit2/Teacher.getClassName:()Ljava/lang/String;
3: astore_1
4: getstatic #22; //Field java/lang/System.out:Ljava/io/PrintStream;
7: aload_1
8: invokevirtual #28; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
11: return
LineNumberTable:
line 13: 0
line 14: 4
line 15: 11
LocalVariableTable:
Start Length Slot Name Signature
0 12 0 args [Ljava/lang/String;
4 8 1 result Ljava/lang/String;
}
D:\work\eclipse\ACP\WydLab\bin>javap -c -verbose pkgname.staticinherit2.Teacher
Compiled from "Teacher.java"
public class pkgname.staticinherit2.Teacher extends pkgname.staticinherit.People
SourceFile: "Teacher.java"
minor version: 0
major version: 46
Constant pool:
const #1 = class #2; // pkgname/staticinherit2/Teacher
const #2 = Asciz pkgname/staticinherit2/Teacher;
const #3 = class #4; // pkgname/staticinherit/People
const #4 = Asciz pkgname/staticinherit/People;
const #5 = Asciz <init>;
const #6 = Asciz ()V;
const #7 = Asciz Code;
const #8 = Method #3.#9; // pkgname/staticinherit/People."<init>":()V
const #9 = NameAndType #5:#6;// "<init>":()V
......
{
public pkgname.staticinherit2.Teacher();
Code:
Stack=1, Locals=1, Args_size=1
0: aload_0
1: invokespecial #8; //Method pkgname/staticinherit/People."<init>":()V
4: return
.....
也就是说,调用的地方“Test.class"里是有"Teacher"这个类的信息的,而Teacher这个类里(如果不覆盖父类的静态方法的话)是根本没有getClassName这个方法的,从Test.class的字节码中找到Teacher类,然后发现没有getClassName方法,然后向上找到父类的静态方法的整个过程,是JVM的字节码引擎处理的,纯java code是无法知道“getClassName"其实是从Teacher类开始找的,除非你的JVM引擎告诉你这些信息。package script;
public class Father {
public void getClassNameDyn() {
new Throwable().printStackTrace();
System.out.println(this.getClass().getName());
}
}
public class Child extends Father{}
public class Test {
public static void main(String[] args) throws Exception {
new Child().getClassNameDyn();
}
}
的返回结果是:
java.lang.Throwable
at script.Father.getClassNameDyn(Father.java:32)
at script.Test.main(Script.java:197)
script.Child
这里Father是编译期特征
如果楼主只想实现单纯的这个需求,我看Teacher.class.getName()就行,你试着把class.getName()想象成一个不变的方法,否则只能传参数了