java 调用本地方法_用Java实现JVM第九章《本地方法调用》

小傅哥 | https://bugstack.cn

沉淀、分享、成长,专注于原创专题案例,以最易学习编程的方式分享知识,让自己和他人都能有所收获。目前已完成的专题有;Netty4.x实战专题案例、用Java实现JVM、基于JavaAgent的全链路监控、手写RPC框架、架构设计专题案例、源码分析等。

你用剑 、我用刀 ,好的代码都很烧,望你不吝出招!

一、案例介绍

本章主要介绍用java实现一些本地方法类库,并初始化本地方法,之后通过反射命令来调用本地方法。Java虚拟机和Java类库一起构成了Java运行时环境。Java类库主要用Java语言编写,一些无法用Java语言实现的方法则使用本地语言编写,这额方法叫作本地方法。

OpenJDK类库中的本地方法是用JNI(Java Native Interface)编写的,但是要让虚拟机支持JNI规范还需要大量工作。

二、环境准备jdk 1.8.0

IntelliJ IDEA Community Edition 2018.3.1 x64

三、配置信息调试配置

11. 配置位置:Run/Debug Configurations -> program arguments

12. 配置内容:-Xjre "C:\Program Files\Java\jdk1.8.0\_161\jre" E:\itstack\git\istack-demo\itstack-demo-jvm\itstack-demo-jvm-09\target\test-classes\org\itstack\demo\test\HelloWorld

四、代码示例

1itstack-demo-jvm-09

2

3├── pom.xml

4

5└── src

6

7 └── main

8

9 │ └── java

10

11 │ └── org.itstack.demo.jvm

12

13 │ ├── \_native

14

15 │ │ ├── java

16

17 │ │ │ ├── \_Class.java

18

19 │ │ │ ├── \_Double.java

20

21 │ │ │ ├── \_Float.java

22

23 │ │ │ ├── \_Object.java

24

25 │ │ │ ├── \_String.java

26

27 │ │ │ └── \_System.java

28

29 │ │ └── sun

30

31 │ ├── NativeMethod.java

32

33 │ └── Registry.java

34

35 │ ├── classfile

36

37 │ │ ├── attributes

38

39 │ │ ├── constantpool

40

41 │ │ ├── ClassFile.java

42

43 │ │ ├── ClassReader.java

44

45 │ │ └── MemberInfo.java

46

47 │ ├── classpath

48

49 │ │ ├── impl

50

51 │ │ │ ├── CompositeEntry.java

52

53 │ │ │ ├── DirEntry.java

54

55 │ │ │ ├── WildcardEntry.java

56

57 │ │ │ └── ZipEntry.java

58

59 │ │ ├── Classpath.java

60

61 │ │ └── Entry.java

62

63 │ ├── classpath

64

65 │ │ ├── base

66

67 │ │ │ ├── BytecodeReader.java

68

69 │ │ │ ├── ClassInitLogic.java

70

71 │ │ │ ├── Instruction.java

72

73 │ │ │ ├── InstructionBranch.java

74

75 │ │ │ ├── InstructionIndex8.java

76

77 │ │ │ ├── InstructionIndex16.java

78

79 │ │ │ ├── InstructionNoOperands.java

80

81 │ │ │ └── MethodInvokeLogic.java

82

83 │ │ ├── comparisons

84

85 │ │ ├── constants

86

87 │ │ ├── control

88

89 │ │ ├── conversions

90

91 │ │ ├── extended

92

93 │ │ ├── loads

94

95 │ │ ├── math

96

97 │ │ ├── references

98

99 │ │ │ ├── ANEW\_ARRAY.java

100

101 │ │ │ ├── ARRAY\_LENGTH.java

102

103 │ │ │ ├── CHECK\_CAST.java

104

105 │ │ │ ├── GET\_FIELD.java

106

107 │ │ │ ├── GET\_STATIC.java

108

109 │ │ │ ├── INSTANCE\_OF.java

110

111 │ │ │ ├── INVOKE\_INTERFACE.java

112

113 │ │ │ ├── INVOKE\_SPECIAL.java

114

115 │ │ │ ├── INVOKE\_STATIC.java

116

117 │ │ │ ├── INVOKE\_VIRTUAL.java

118

119 │ │ │ ├── MULTI\_ANEW\_ARRAY.java

120

121 │ │ │ ├── NEW.java

122

123 │ │ │ ├── NEW\_ARRAY.java

124

125 │ │ │ ├── PUT\_FIELD.java

126

127 │ │ │ └── PUT\_STATIC.java

128

129 │ │ ├── reserved

130

131 │ │ │ └── INVOKE\_NATIVE.java

132

133 │ │ ├── stack

134

135 │ │ ├── store

136

137 │ │ │ └── xastore

138

139 │ │ │ ├── AASTORE.java

140

141 │ │ │ ├── BASTORE.java

142

143 │ │ │ ├── CASTORE.java

144

145 │ │ │ ├── DASTORE.java

146

147 │ │ │ ├── FASTORE.java

148

149 │ │ │ ├── IASTORE.java

150

151 │ │ │ ├── LASTORE.java

152

153 │ │ │ └── SASTORE.java

154

155 │ │ └── Factory

156

157 │ ├── rtda

158

159 │ │ ├── heap

160

161 │ │ │ ├── constantpool

162

163 │ │ │ ├── methodarea

164

165 │ │ │ │ ├── Class.java

166

167 │ │ │ │ ├── ClassMember.java

168

169 │ │ │ │ ├── Field.java

170

171 │ │ │ │ ├── Method.java

172

173 │ │ │ │ ├── MethodDescriptor.java

174

175 │ │ │ │ ├── MethodDescriptorParser.java

176

177 │ │ │ │ ├── MethodLookup.java

178

179 │ │ │ │ ├── Object.java

180

181 │ │ │ │ ├── Slots.java

182

183 │ │ │ │ └── StringPool.java

184

185 │ │ │ └── ClassLoader.java

186

187 │ │ ├── Frame.java

188

189 │ │ ├── JvmStack.java

190

191 │ │ ├── LocalVars.java

192

193 │ │ ├── OperandStack.java

194

195 │ │ ├── Slot.java

196

197 │ │ └── Thread.java

198

199 │ ├── Cmd.java

200

201 │ ├── Interpret.java

202

203 │ └── Main.java

204

205 └── test

206

207 └── java

208

209 └── org.itstack.demo.test

210

211 └── HelloWorld.java

代码片段_Class.java

1package org.itstack.demo.jvm.\_native.java;

2

3

4

5import org.itstack.demo.jvm.\_native.NativeMethod;

6

7import org.itstack.demo.jvm.\_native.Registry;

8

9import org.itstack.demo.jvm.rtda.Frame;

10

11import org.itstack.demo.jvm.rtda.LocalVars;

12

13import org.itstack.demo.jvm.rtda.OperandStack;

14

15import org.itstack.demo.jvm.rtda.heap.ClassLoader;

16

17import org.itstack.demo.jvm.rtda.heap.methodarea.Class;

18

19import org.itstack.demo.jvm.rtda.heap.methodarea.Object;

20

21import org.itstack.demo.jvm.rtda.heap.methodarea.StringPool;

22

23

24

25/\*\*

26

27 \* https://bugstack.cn/

28

29 \* create by fuzhengwei on 2019/4/30

30

31 \*/

32

33public class \_Class {

34

35

36

37 private final String jlClass = "java/lang/Class";

38

39

40

41 public \_Class() {

42

43 Registry.register(jlClass, "getPrimitiveClass", "(Ljava/lang/String;)Ljava/lang/Class;", new NativeMethod(this, "getPrimitiveClass"));

44

45 Registry.register(jlClass, "getName0", "()Ljava/lang/String;", new NativeMethod(this, "getName0"));

46

47 Registry.register(jlClass, "desiredAssertionStatus0", "(Ljava/lang/Class;)Z", new NativeMethod(this, "desiredAssertionStatus0"));

48

49 Registry.register(jlClass, "registerNatives", "()V", new NativeMethod(this, "registerNatives"));

50

51 }

52

53

54

55 public void registerNatives(Frame frame) {

56

57 // do nothing

58

59 }

60

61

62

63 public void getPrimitiveClass(Frame frame) {

64

65 Object nameObj = frame.localVars().getRef(0);

66

67 String name = StringPool.goString(nameObj);

68

69

70

71 ClassLoader loader = frame.method().clazz().loader();

72

73 Object jClass = loader.loadClass(name).jClass();

74

75

76

77 frame.operandStack().pushRef(jClass);

78

79 }

80

81

82

83 public void getName0(Frame frame) {

84

85 Object thiz = frame.localVars().getThis();

86

87 Class clazz = (Class) thiz.extra();

88

89

90

91 String name = "虚拟机本地方法getName0获取类名:" + clazz.javaName();

92

93 Object nameObj = StringPool.jString(clazz.loader(), name);

94

95

96

97 frame.operandStack().pushRef(nameObj);

98

99 }

100

101

102

103 public void desiredAssertionStatus0(Frame frame) {

104

105 frame.operandStack().pushBoolean(false);

106

107 }

108

109

110

111 public void isInterface(Frame frame) {

112

113 LocalVars vars = frame.localVars();

114

115 Object thiz = vars.getThis();

116

117 Class clazz = (Class) thiz.extra();

118

119

120

121 OperandStack stack = frame.operandStack();

122

123 stack.pushBoolean(clazz.isInterface());

124

125 }

126

127

128

129 public void isPrimitive(Frame frame) {

130

131 LocalVars vars = frame.localVars();

132

133 Object thiz = vars.getThis();

134

135 Class clazz = (Class) thiz.extra();

136

137

138

139 OperandStack stack = frame.operandStack();

140

141 stack.pushBoolean(clazz.IsPrimitive());

142

143 }

144

145

146

147}_System.java

1package org.itstack.demo.jvm.\_native.java;

2

3

4

5import org.itstack.demo.jvm.\_native.NativeMethod;

6

7import org.itstack.demo.jvm.\_native.Registry;

8

9import org.itstack.demo.jvm.rtda.Frame;

10

11import org.itstack.demo.jvm.rtda.LocalVars;

12

13import org.itstack.demo.jvm.rtda.heap.methodarea.Class;

14

15import org.itstack.demo.jvm.rtda.heap.methodarea.Object;

16

17

18

19/\*\*

20

21 \* https://bugstack.cn/

22

23 \* create by fuzhengwei on 2019/4/30

24

25 \*/

26

27public class \_System {

28

29

30

31 private final String jlSystem = "java/lang/System";

32

33

34

35 public \_System() {

36

37 Registry.register(jlSystem, "arraycopy", "()Ljava/lang/String;", new NativeMethod(this, "arraycopy"));

38

39 Registry.register(jlSystem,"registerNatives", "()V",new NativeMethod(this,"registerNatives"));

40

41 }

42

43

44

45 public void registerNatives(Frame frame) {

46

47 // do nothing

48

49 }

50

51

52

53 public void arraycopy(Frame frame) {

54

55 LocalVars vars = frame.localVars();

56

57 Object src = vars.getRef(0);

58

59 int srcPos = vars.getInt(1);

60

61 Object dest = vars.getRef(2);

62

63 int destPos = vars.getInt(4);

64

65 int length = vars.getInt(4);

66

67

68

69 if (null == src || dest == null) {

70

71 throw new NullPointerException();

72

73 }

74

75

76

77 if (!checkArrayCopy(src, dest)) {

78

79 throw new ArrayStoreException();

80

81 }

82

83

84

85 if (srcPos < 0 || destPos < 0 || length < 0 ||

86

87 srcPos + length > src.arrayLength() ||

88

89 destPos + length > dest.arrayLength()) {

90

91 throw new IndexOutOfBoundsException();

92

93 }

94

95

96

97 System.arraycopy(src, srcPos, dest, destPos, length);

98

99

100

101 //todo 待完善

102

103

104

105 }

106

107

108

109 public boolean checkArrayCopy(Object src, Object dest) {

110

111 Class srcClass = src.clazz();

112

113 Class destClass = dest.clazz();

114

115

116

117 if (!srcClass.isArray() || !destClass.isArray()) {

118

119 return false;

120

121 }

122

123

124

125 if (srcClass.componentClass().IsPrimitive() || destClass.componentClass().IsPrimitive()) {

126

127 return srcClass == destClass;

128

129 }

130

131

132

133 return true;

134

135

136

137 }

138

139

140

141}NativeMethod.java

1package org.itstack.demo.jvm.\_native;

2

3

4

5import org.itstack.demo.jvm.rtda.Frame;

6

7

8

9import java.lang.reflect.Method;

10

11

12

13/\*\*

14

15 \* https://bugstack.cn/

16

17 \* create by fuzhengwei on 2019/4/30

18

19 \*/

20

21public class NativeMethod {

22

23

24

25 private String methodName;

26

27 private Object obj;

28

29

30

31 public NativeMethod(Object obj, String methodName) {

32

33 this.methodName = methodName;

34

35 this.obj = obj;

36

37 }

38

39

40

41 public void invoke(Frame frame) {

42

43 try {

44

45 Method method = obj.getClass().getMethod(methodName, frame.getClass());

46

47 method.invoke(obj, frame);

48

49 } catch (Exception e) {

50

51 e.printStackTrace();

52

53 }

54

55 }

56

57

58

59}Registry.java

1package org.itstack.demo.jvm.\_native;

2

3

4

5import org.itstack.demo.jvm.\_native.java.\*;

6

7

8

9import java.util.HashMap;

10

11import java.util.Map;

12

13

14

15/\*\*

16

17 \* https://bugstack.cn/

18

19 \* create by fuzhengwei on 2019/4/30

20

21 \*/

22

23public class Registry {

24

25

26

27 private static Map registry = new HashMap<>();

28

29

30

31 //初始化本地方法

32

33 public static void initNative() {

34

35 new \_Class();

36

37 new \_Double();

38

39 new \_Float();

40

41 new \_Object();

42

43 new \_String();

44

45 new \_System();

46

47 }

48

49

50

51 public static void register(String className, String methodName, String methodDescriptor, NativeMethod method) {

52

53 String key = className + "~" + methodName + "~" + methodDescriptor;

54

55 registry.put(key, method);

56

57 }

58

59

60

61 public static NativeMethod findNativeMethod(String className, String methodName, String methodDescriptor) {

62

63 String key = className + "~" + methodName + "~" + methodDescriptor;

64

65 return registry.get(key);

66

67 }

68

69

70

71}INVOKE_NATIVE.java

1package org.itstack.demo.jvm.instructions.reserved;

2

3

4

5import org.itstack.demo.jvm.\_native.NativeMethod;

6

7import org.itstack.demo.jvm.\_native.Registry;

8

9import org.itstack.demo.jvm.instructions.base.InstructionNoOperands;

10

11import org.itstack.demo.jvm.rtda.Frame;

12

13import org.itstack.demo.jvm.rtda.heap.methodarea.Method;

14

15

16

17/\*\*

18

19 \* https://bugstack.cn/

20

21 \* create by fuzhengwei on 2019/5/2

22

23 \*/

24

25public class INVOKE\_NATIVE extends InstructionNoOperands {

26

27

28

29 @Override

30

31 public void execute(Frame frame) {

32

33 Method method = frame.method();

34

35 String className = method.clazz().name();

36

37 String methodName = method.name();

38

39 String methodDescriptor = method.descriptor();

40

41

42

43 NativeMethod nativeMethod = Registry.findNativeMethod(className, methodName, methodDescriptor);

44

45 if (null == nativeMethod) {

46

47 String methodInfo = className + "." + methodName + methodDescriptor;

48

49 throw new UnsatisfiedLinkError(methodInfo);

50

51 }

52

53

54

55 nativeMethod.invoke(frame);

56

57

58

59 }

60

61

62

63}ClassLoader.java

1package org.itstack.demo.jvm.rtda.heap;

2

3

4

5import org.itstack.demo.jvm.classfile.ClassFile;

6

7import org.itstack.demo.jvm.classpath.Classpath;

8

9import org.itstack.demo.jvm.rtda.heap.constantpool.AccessFlags;

10

11import org.itstack.demo.jvm.rtda.heap.methodarea.\*;

12

13import org.itstack.demo.jvm.rtda.heap.constantpool.RunTimeConstantPool;

14

15import org.itstack.demo.jvm.rtda.heap.methodarea.Class;

16

17import org.itstack.demo.jvm.rtda.heap.methodarea.Object;

18

19

20

21import java.util.HashMap;

22

23import java.util.Map;

24

25

26

27/\*

28

29class names:

30

31 - primitive types: boolean, byte, int ...

32

33 - primitive arrays: [Z, [B, [I ...

34

35 - non-array classes: java/lang/Object ...

36

37 - array classes: [Ljava/lang/Object; ...

38

39\*/

40

41public class ClassLoader {

42

43

44

45 private Classpath classpath;

46

47 private Map classMap;

48

49

50

51 public ClassLoader(Classpath classpath) {

52

53 this.classpath = classpath;

54

55 this.classMap = new HashMap<>();

56

57

58

59 this.loadBasicClasses();

60

61 this.loadPrimitiveClasses();

62

63 }

64

65

66

67 private void loadBasicClasses() {

68

69 Class jlClassClass = this.loadClass("java/lang/Class");

70

71 for (Map.Entry entry : this.classMap.entrySet()) {

72

73 Class clazz = entry.getValue();

74

75 if (clazz.jClass == null) {

76

77 clazz.jClass = jlClassClass.newObject();

78

79 clazz.jClass.extra = clazz;

80

81 }

82

83 }

84

85 }

86

87

88

89 private void loadPrimitiveClasses() {

90

91 for (Map.Entry entry : ClassNameHelper.primitiveTypes.entrySet()) {

92

93 loadPrimitiveClass(entry.getKey());

94

95 }

96

97 }

98

99

100

101 private void loadPrimitiveClass(String className) {

102

103 Class clazz = new Class(AccessFlags.ACC\_PUBLIC,

104

105 className,

106

107 this,

108

109 true);

110

111 clazz.jClass = this.classMap.get("java/lang/Class").newObject();

112

113 clazz.jClass.extra = clazz;

114

115 this.classMap.put(className, clazz);

116

117 }

118

119

120

121 public Class loadClass(String className) {

122

123 Class clazz = classMap.get(className);

124

125 if (null != clazz) return clazz;

126

127

128

129 //'['数组标识

130

131 if (className.getBytes()[0] == '[') {

132

133 clazz = loadArrayClass(className);

134

135 } else {

136

137 clazz = loadNonArrayClass(className);

138

139 }

140

141

142

143 Class jlClazz = this.classMap.get("java/lang/Class");

144

145 if (null != jlClazz && null != clazz) {

146

147 clazz.jClass = jlClazz.newObject();

148

149 clazz.jClass.extra = clazz;

150

151 }

152

153

154

155 return clazz;

156

157 }

158

159

160

161 private Class loadArrayClass(String className) {

162

163 Class clazz = new Class(AccessFlags.ACC\_PUBLIC,

164

165 className,

166

167 this,

168

169 true,

170

171 this.loadClass("java/lang/Object"),

172

173 new Class[]{

174

175 this.loadClass("java/lang/Cloneable"),

176

177 this.loadClass("java/io/Serializable")});

178

179 this.classMap.put(className, clazz);

180

181 return clazz;

182

183 }

184

185

186

187 private Class loadNonArrayClass(String className) {

188

189 try {

190

191 byte[] data = this.classpath.readClass(className);

192

193 if (null == data) {

194

195 throw new ClassNotFoundException(className);

196

197 }

198

199 Class clazz = defineClass(data);

200

201 link(clazz);

202

203 return clazz;

204

205 } catch (Exception e) {

206

207 e.printStackTrace();

208

209 return null;

210

211 }

212

213 }

214

215

216

217 private void link(Class clazz) {

218

219 verify(clazz);

220

221 prepare(clazz);

222

223 }

224

225

226

227 private void prepare(Class clazz) {

228

229 calcInstanceFieldSlotIds(clazz);

230

231 calcStaticFieldSlotIds(clazz);

232

233 allocAndInitStaticVars(clazz);

234

235 }

236

237

238

239 private void allocAndInitStaticVars(Class clazz) {

240

241 clazz.staticVars = new Slots(clazz.staticSlotCount);

242

243 for (Field field : clazz.fields) {

244

245 if (field.isStatic() && field.isFinal()) {

246

247 initStaticFinalVar(clazz, field);

248

249 }

250

251 }

252

253 }

254

255

256

257 private void initStaticFinalVar(Class clazz, Field field) {

258

259 Slots staticVars = clazz.staticVars;

260

261 RunTimeConstantPool constantPool = clazz.runTimeConstantPool;

262

263 int cpIdx = field.constValueIndex();

264

265 int slotId = field.slotId();

266

267

268

269 if (cpIdx > 0) {

270

271 switch (field.descriptor()) {

272

273 case "Z":

274

275 case "B":

276

277 case "C":

278

279 case "S":

280

281 case "I":

282

283 java.lang.Object val = constantPool.getConstants(cpIdx);

284

285 staticVars.setInt(slotId, (Integer) val);

286

287 break;

288

289 case "J":

290

291 staticVars.setLong(slotId, (Long) constantPool.getConstants(cpIdx));

292

293 break;

294

295 case "F":

296

297 staticVars.setFloat(slotId, (Float) constantPool.getConstants(cpIdx));

298

299 break;

300

301 case "D":

302

303 staticVars.setDouble(slotId, (Double) constantPool.getConstants(cpIdx));

304

305 break;

306

307 case "Ljava/lang/String;":

308

309 String goStr = (String) constantPool.getConstants(cpIdx);

310

311 Object jStr = StringPool.jString(clazz.loader(), goStr);

312

313 staticVars.setRef(slotId, jStr);

314

315 break;

316

317 }

318

319 }

320

321

322

323 }

324

325

326

327 private void calcStaticFieldSlotIds(Class clazz) {

328

329 int slotId = 0;

330

331 for (Field field : clazz.fields) {

332

333 if (field.isStatic()) {

334

335 field.slotId = slotId;

336

337 slotId++;

338

339 if (field.isLongOrDouble()) {

340

341 slotId++;

342

343 }

344

345 }

346

347 }

348

349 clazz.staticSlotCount = slotId;

350

351 }

352

353

354

355 private void calcInstanceFieldSlotIds(Class clazz) {

356

357 int slotId = 0;

358

359 if (clazz.superClass != null) {

360

361 slotId = clazz.superClass.instanceSlotCount;

362

363 }

364

365 for (Field field : clazz.fields) {

366

367 if (!field.isStatic()) {

368

369 field.slotId = slotId;

370

371 slotId++;

372

373 if (field.isLongOrDouble()) {

374

375 slotId++;

376

377 }

378

379 }

380

381 }

382

383 clazz.instanceSlotCount = slotId;

384

385 }

386

387

388

389 private void verify(Class clazz) {

390

391 // 校验字节码,尚未实现

392

393 }

394

395

396

397 private Class defineClass(byte[] data) throws Exception {

398

399 Class clazz = parseClass(data);

400

401 clazz.loader = this;

402

403 resolveSuperClass(clazz);

404

405 resolveInterfaces(clazz);

406

407 this.classMap.put(clazz.name, clazz);

408

409 return clazz;

410

411 }

412

413

414

415 private void resolveInterfaces(Class clazz) throws Exception {

416

417 int interfaceCount = clazz.interfaceNames.length;

418

419 if (interfaceCount > 0) {

420

421 clazz.interfaces = new Class[interfaceCount];

422

423 for (int i = 0; i < interfaceCount; i++) {

424

425 clazz.interfaces[i] = clazz.loader.loadClass(clazz.interfaceNames[i]);

426

427 }

428

429 }

430

431 }

432

433

434

435 private void resolveSuperClass(Class clazz) throws Exception {

436

437 if (!clazz.name.equals("java/lang/Object")) {

438

439 clazz.superClass = clazz.loader.loadClass(clazz.superClassName);

440

441 }

442

443 }

444

445

446

447 private Class parseClass(byte[] data) {

448

449 ClassFile classFile = new ClassFile(data);

450

451 return new Class(classFile);

452

453 }

454

455

456

457

458

459}HelloWorld.java

1package org.itstack.demo.test;

2

3

4

5/\*\*

6

7 \* -Xjre "C:\Program Files\Java\jdk1.8.0\_161\jre" E:\itstack\git\istack-demo\itstack-demo-jvm\itstack-demo-jvm-09\target\test-classes\org\itstack\demo\test\HelloWorld -verbose true -args 你好,java版虚拟机v1.0,欢迎你的到来。

8

9 \*/

10

11public class HelloWorld {

12

13

14

15 public static void main(String[] args) {

16

17 System.out.println(byte.class.getName()); // byte

18

19 System.out.println(void.class.getName()); // void

20

21 System.out.println(boolean.class.getName()); // boolean

22

23 System.out.println(char.class.getName()); // cha

24

25 System.out.println(short.class.getName()); // short

26

27 System.out.println(int.class.getName()); // int

28

29 System.out.println(long.class.getName()); // long

30

31 System.out.println(float.class.getName()); // float

32

33 System.out.println(double.class.getName()); // double

34

35 System.out.println(Object.class.getName()); // java.lang.Object

36

37 System.out.println(int[].class.getName()); // [I

38

39 System.out.println(int[][].class.getName()); // [[I

40

41 System.out.println(Object[].class.getName()); // [Ljava.lang.Object;

42

43 System.out.println(Object[][].class.getName()); // [[Ljava.lang.Object;

44

45 }

46

47

48

49}

五、测试结果

1虚拟机本地方法getName0获取类名:byte

2

3虚拟机本地方法getName0获取类名:void

4

5虚拟机本地方法getName0获取类名:boolean

6

7虚拟机本地方法getName0获取类名:cha

8

9虚拟机本地方法getName0获取类名:short

10

11虚拟机本地方法getName0获取类名:int

12

13虚拟机本地方法getName0获取类名:long

14

15虚拟机本地方法getName0获取类名:float

16

17虚拟机本地方法getName0获取类名:double

18

19虚拟机本地方法getName0获取类名:java.lang.Object

20

21虚拟机本地方法getName0获取类名:[I

22

23虚拟机本地方法getName0获取类名:[[I

24

25虚拟机本地方法getName0获取类名:[Ljava.lang.Object;

26

27虚拟机本地方法getName0获取类名:[[Ljava.lang.Object;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值