JAVA怎么给一个对象动态添加属性

JAVA怎么给一个对象动态添加属性,第1张

给某个对象动态不了属性

但是可以通过集合类来实现

例如你可以用Map这个类来实现

map.put(key,value)

键值对都是泛型

之后通过map.get(key)来获取

给某个对象动态不了属性的

但是可以通过集合类来实现

例如你可以用Map这个类来实现

map.put(key,value)

键值对都是泛型

之后通过map.get(key)来获取

可以的,你用 javassist, cglib 或者更为底层的工具 ASM 都是可以。

ASM 的话相对复杂一些,参考代码:

下面这个是用 ASM 工具为 Student 类添加一个 public String 类型的 address 属性:

1,需要添加属性的原始类:Student.java

Java code?

public class Student {

private int age

private String name

public int getAge() {

return age

}

public void setAge(int age) {

this.age = age

}

public String getName() {

return name

}

public void setName(String name) {

this.name = name

}

}

2,添加属性的适配器:AddFieldAdapter.java

Java code?

import org.objectweb.asm.ClassAdapter

import org.objectweb.asm.ClassVisitor

import org.objectweb.asm.FieldVisitor

public class AddFieldAdapter extends ClassAdapter {

private int accessModifier

private String name

private String desc

private boolean isFieldPresent

public AddFieldAdapter(ClassVisitor cv, int accessModifier, String name, String desc) {

super(cv)

this.accessModifier = accessModifier

this.name = name

this.desc = desc

}

@Override

public FieldVisitor visitField(int access, String name, String desc,

String signature, Object value) {

if (name.equals(this.name)) {

isFieldPresent = true

}

return cv.visitField(access, name, desc, signature, value)

}

@Override

public void visitEnd() {

if (!isFieldPresent) {

FieldVisitor fv = cv.visitField(accessModifier, name, desc, null, null)

if (fv != null) {

fv.visitEnd()

}

}

cv.visitEnd()

}

}

3,添加属性的工具 AddField.java

Java code?

import java.io.File

import java.io.FileOutputStream

import java.io.IOException

import java.io.OutputStream

import org.objectweb.asm.ClassAdapter

import org.objectweb.asm.ClassReader

import org.objectweb.asm.ClassWriter

import org.objectweb.asm.Opcodes

public class AddField {

private Class clazz = null

private ClassReader cr = null

private ClassWriter cw = null

private ClassAdapter ca = null

private File classFile = null

private final static String CLASS_FILE_SUFFIX = ".class"

public AddField(Class clazz) {

this.clazz = clazz

}

/**

* 添加一个 public 的类成员

* @param fieldName 类成员名

* @param fieldDesc 类成员类型描述

*/

public void addPublicField(String fieldName, String fieldDesc) {

if(cr == null) {

try {

cr = new ClassReader(clazz.getCanonicalName())

} catch (IOException e) {

e.printStackTrace()

}

cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS)

}

if(ca == null) {

ca = new AddFieldAdapter(cw, Opcodes.ACC_PUBLIC, fieldName, fieldDesc)

} else {

ca = new AddFieldAdapter(ca, Opcodes.ACC_PUBLIC, fieldName, fieldDesc)

}

}

/**

* 将字节码写入类的 .class 文件

*

*/

public void writeByteCode() {

cr.accept(ca, ClassReader.SKIP_DEBUG)

byte[] bys = cw.toByteArray()

OutputStream os = null

try {

os = new FileOutputStream(getFile())

os.write(bys)

} catch (IOException e) {

e.printStackTrace()

} finally {

try {

os.close()

} catch (IOException e) {

e.printStackTrace()

}

}

}

/**

* 获得类文件的 File 对象

* @return

*/

private File getFile() {

if(classFile == null) {

StringBuffer sb = new StringBuffer()

sb.append(clazz.getResource("/"))

.append(clazz.getCanonicalName().replace(".", File.separator))

.append(CLASS_FILE_SUFFIX)

classFile = new File(sb.substring(6))

}

return classFile

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11760666.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-18
下一篇 2023-05-18

发表评论

登录后才能评论

评论列表(0条)

保存