譬如如下代码public class A
{
public static void main(String[] args)
{
A a = new A();
}
}现在我希望临时给这个a加个属性name
可以获得a.name = "xxx";
同时不修改A这个class
JAVA可以实现吗?如何实现呢?
初学JAVA,谢谢~~~~

解决方案 »

  1.   

    此回复为自动发出,仅用于显示而已,并无任何其他特殊作用
    楼主【Aimar】截止到2008-07-19 07:21:50的历史汇总数据(不包括此帖):
    发帖的总数量:2                        发帖的总分数:0                        每贴平均分数:0                        
    回帖的总数量:0                        得分贴总数量:0                        回帖的得分率:0%                       
    结贴的总数量:2                        结贴的总分数:0                        
    无满意结贴数:2                        无满意结贴分:40                       
    未结的帖子数:0                        未结的总分数:0                        
    结贴的百分比:100.00%               结分的百分比:---------------------
    无满意结贴率:100.00%               无满意结分率:---------------------
    敬礼!
      

  2.   

    可以 
    public class A
    {
    String name;
    public static void main(String[] args)
    {
    A a = new A();
    a.name = "asd";
    }
    }
      

  3.   

    那我换个说法class A
    {
      private A()
      {
      }
      public A make()
      {
        return new A();
      }
    }
    class B
    {
      public static void main(String[] args)
      {
        A a = new A();
      }
    }在B类里面不修改A给这个a对添加个name字段呢?
      

  4.   

    额,感谢您的回复
    不过,我希望的是在不修改A的情况下,譬如你这个A是JDK自带的
    就拿socket举例把
    class A
    {
      public static void main(String[] args)
      {
        socket = serverSocket.accept();
      }
    }
    现在我要求给这个socket加个name字段,能实现吗?
      

  5.   

    楼主刚学完 JavaScript 吧,JavaScript 可以,但 Java 不可以。
      

  6.   

    我只知道asm,cglib可以动态的修改类,但没听说过可以修改对象的。
    不能帮助到你
      

  7.   

    继承.这是继承解决的问题......
    class B extends A{
        String name;
        public void setName(String name){
            this.name = name;
        }
        public String getName(){
            return name;
        }
    }
      

  8.   

    按照你的要求,肯定地说,无法实现。不过可以有类似的解决办法。
    如果说,是JDK自带的类,唯一方法只能继承。
    如果是自己写的类,可以给类加一个Map<String,Object>字段。
    添加String name,直接写进Map。
      

  9.   

    你给java开发小组写封信 ,问问他们下一步是不是要做这个
      

  10.   

    按照lz的想法,如果是在程序中实现这个功能应该用继承吧(会增加一个类)
    另外Java SE 6 新特性: Instrumentation 新功能:能够替换和修改某些类的定义(虚拟机启动后的动态的操作类)
      

  11.   

    通过程序修改 .class 文件!下面这个是用 ASM 工具为 Student 类添加一个 public String 类型的 address 属性:1,需要添加属性的原始类:Student.javapublic 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.javaimport 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.javaimport 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;
        }
    }
    4,字节码处理:PreCompileProcess.javapublic class PreCompileProcess {    public static void main(String[] args) {        // 为 Student 添加字段
            AddField add = new AddField(Student.class);        // 添加一个名为 address,类型为 java.lang.String 的 public 字段 
            add.addPublicField("address", "Ljava/lang/String;");        // 再增加一个名为 tel,类型为 int 的 public 方法
            add.addPublicField("tel", "I");        // 重新生成 .class 文件
            add.writeByteCode();
        }
    }
    5,测试类:Test.javapublic class Test {    public static void main(String[] args) {
            Student stu = new Student();
            stu.setAge(10);
            stu.setName("Tom");
            stu.address = "Beijing";    // 新增加的 address 字段
            stu.tel = 56;               // 新增加的 tel 字段
            System.out.println("Name:    " + stu.getName());
            System.out.println("Age:     " + stu.getAge());
            System.out.println("Address: " + stu.address);
            System.out.println("Tel:     " + stu.tel);
        }
    }上面的代码需要 ASM 工具才能进行编译,ASM 可以到 http://asm.objectweb.org/ 上面去下载。执行顺序:javac Student.java
    javac -cp .;lib/asm-all-3.1.jar PreCompileProcess.java
    java -cp .;lib/asm-all-3.1.jar PreCompileProcess
    javac Test.java
    java Test在 Student.java 没有修改的情况下,PreCompileProcess 只需要执行一次就可以了。
      

  12.   

    据我所知,不借用其他工具,光JDK而言是做不到的吧……
      

  13.   


    如果你的类是自己写的,那你可以通过 ASM 工具来动态地添加属性。如果是 JDK 自带的,你是不能去修改他的字节码而新增加一个属性的,
    可以采用继承的方式为其添加一个属性。而且 ASM 只能修改字节码而为类增加新的属性无论用何种方法绝对不可能在对象上面添加一个属性的!
      

  14.   

    楼上的说的太绝对了!
    Sun有工具包可以动态给程序增加新的方法和属性的。
    sun.reflect包 自己去看相关的api吧~
    不过这个是sun的私有包、相关资料不是很齐全~
      

  15.   


    不行的。不过可以在A里面放一个HashTable或者是其他的。可以对A里的这个HashTable进行添加字段或其他操作。
      

  16.   

    修改class类相当于修改了代码,不推荐。
      

  17.   

    本来我也在考虑这个问题,经过大家的提示我考虑了一种办法。
    首先界定  楼主的要求 是 任意给一个(自己创建的)object,可以在里面动态的添加属性,甚至方法。
     我认为楼主的方法很好啊。毕竟能够减少很多的java对象,尤其是数据库操作非常有用。(可能会照成不易理解,因为会导致太多的配置信息)。方法:就是创建一个基础对象,在其内部创建一个HashMap ,然后就可以动态添加 名称和对象了。 如果复杂一点可以 创建一个 属性类,可以明确表明 属性名称,类型,缺省值等。   1、创建一个接口 
        public interface IDynamicObject{
            public boolean addProperty(String propertyName,Object propertyObject);
            public boolean addMethod(String methodName, MethodInterface methodObject);
            public Object getPropertyOrMethod(String name);
            public List getPropertyOrMethodNames(); 
        }
        2、创建一个实现接口类 即可。
        DynamicObject implements IDynamicObject{
           private Hashmap propertyAndMethodMap = new HashMap(16);
         /*  下面就是 依据这个hashMap 来实现上面的接口。
               
         */
        }
      

  18.   

    寒、下一步SUN团队要解决的问题! 很实际的问题!
      

  19.   

    33楼的同志,方法可行。但就是有一点,
    stu.address = "Beijing";    
    stu.tel = 56;   
    System.out.println("Address: " + stu.address);
    System.out.println("Tel:     " + stu.tel);
    的address和tel显示为错误,能否去除“红色”标记?已经很感谢了