0 0

java动态的给对象附加属性。20

假如现在有一个属性配置文件,我需要去读取里面的属性并且是产生一个对象获取它,比如有一个xxx.txt文件:

a = 1

b = "hello"

 

我现在调用如下语句:

neatpropertybundle property  = new neatpropertybundleproperty("xxx.txt");

 

调用Systen.out.println(property.a),System.out.println(property.b);

代理的话如何实现,或者实现就行。


问题补充:<div class="quote_title">duanhengtao03 写道</div><div class="quote_div">只是读出他的value吗?</div> <br />是的,一定要通过调用属性的方式。。

问题补充:<div class="quote_title">jbutton 写道</div><div class="quote_div">通过程序修改 .class 文件!<strong>&lt;&lt;希望你参考下&gt;&gt;</strong> <br />下面这个是用 ASM 工具为 Student 类添加一个 public String 类型的 address 属性: <br /><strong>1,需要添加属性的原始类:Student.java</strong> <br /><pre name="code" class="java">
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;
    }   
}
</pre> <br /><strong>2,添加属性的适配器:AddFieldAdapter.java</strong> <br /><pre name="code" class="java">
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();
    }
}

</pre> <br /><strong>3,添加属性的工具 AddField.java</strong> <br /><pre name="code" class="java">
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;
    }
}
</pre> <br /><strong>4,字节码处理:PreCompileProcess.java</strong> <br /><pre name="code" class="java">
public 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();
    }
}
</pre> <br /><strong>5,测试类:Test.java</strong> <br /><pre name="code" class="java">
public 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);
    }
}
</pre> <br /></div> <br />帅哥,我刚打完球,看了一下,怎么还是通过方法获取属性的,我想表达的意思是通过属性!

问题补充:<div class="quote_title">jbutton 写道</div><div class="quote_div">通过程序修改 .class 文件!<strong>&lt;&lt;希望你参考下&gt;&gt;</strong> <br />下面这个是用 ASM 工具为 Student 类添加一个 public String 类型的 address 属性: <br /><strong>1,需要添加属性的原始类:Student.java</strong> <br /><pre name="code" class="java">
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;
    }   
}
</pre> <br /><strong>2,添加属性的适配器:AddFieldAdapter.java</strong> <br /><pre name="code" class="java">
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();
    }
}

</pre> <br /><strong>3,添加属性的工具 AddField.java</strong> <br /><pre name="code" class="java">
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;
    }
}
</pre> <br /><strong>4,字节码处理:PreCompileProcess.java</strong> <br /><pre name="code" class="java">
public 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();
    }
}
</pre> <br /><strong>5,测试类:Test.java</strong> <br /><pre name="code" class="java">
public 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);
    }
}
</pre> <br /></div> <br />这是一道thinking in patters上的练习题!
2011年3月28日 15:21

4个答案 按时间排序 按投票排序

0 0

通过属性来访问?

2011年4月12日 18:29
0 0

通过程序修改 .class 文件!<<希望你参考下>>
下面这个是用 ASM 工具为 Student 类添加一个 public String 类型的 address 属性:
1,需要添加属性的原始类:Student.java

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
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
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;
    }
}

4,字节码处理:PreCompileProcess.java
public 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.java
public 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);
    }
}

2011年3月28日 16:56
0 0

读取类:

package com.servlet.common;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public final class Config {
	private Config(){
		
	}
	/*
	 * 指定要加载的配置文件
	 */
	private static String config="/config.properties";
	/*
	 * 创建一个Properties的对象,即一个空的属性集
	 * 属性列表中的每个键及其对应值都是一个字符串
	 */
	private static Properties prop =null ;
	static{
		prop=new Properties();
		    try {
		    	/*
		    	 * 创建一个输入流
		    	 * Config.class表示获得当前类的一个实例
		    	 */
		    	InputStream is = Config.class.getResourceAsStream(config);
				prop.load(is);//从一个流中加载Properties
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		
	}
	/**
	 * 获得当前属性集的key所对应的Value
	 * @param key
	 * @return
	 */
	public static String getString(String key){
		if(null!=prop){
			return prop.getProperty(key);
		}else{
			return "def";
		}
	}

}

这是配置文件:
java.driver.name=com.mysql.jdbc.Driver
java.db.url=jdbc:mysql://localhost/t24
java.db.username=root
java.db.password=root

希望对你有帮助!

2011年3月28日 15:44
0 0

只是读出他的value吗?

2011年3月28日 15:23

相关推荐

    accp7.0使用Java实现面向对象编程

    在Java中,我们通过定义类(Class)来实现封装,类是对象的模板,它包含了属性(Fields,即数据成员)和方法(Methods,即行为)。我们可以通过访问修饰符(public, private, protected)来控制属性和方法的可见性,...

    <java面向对象编程>孙卫琴课后答案

    2. **封装**:封装是面向对象编程的基础原则之一,通过封装,我们可以隐藏对象的内部实现细节,只暴露必要的接口给外部使用。在Java中,我们使用访问修饰符(如private, public, protected)来控制类的成员对外的...

    Java语言的动态属性总结[参考].pdf

    Java语言的动态属性是其灵活性和可扩展性的关键特性之一,允许程序在运行时检查、修改和调用类的属性和方法。以下是对这些概念的详细说明: 1. **Java.lang.Class**: 这个类提供了关于Java类的元数据信息,如构造...

    基于java的面向对象编程ppt

    **Java面向对象编程基础** Java是一种广泛使用的编程语言,以其“一次编写,到处运行”的特性闻名,尤其在企业级应用开发中占据主导地位。面向对象编程(Object-Oriented Programming,OOP)是Java的核心概念,它...

    java判断题

    一个类可以用来创建多个对象实例,这些对象共享相同的属性定义,但每个对象的具体属性值可以不同。 2. **当运行javac命令对一个java源程序进行编译时,必须写出该源程序文件的完整文件名,包括扩展名.java。(T)**...

    《Java面向对象程序设计》

    《Java面向对象程序设计》是一本深入探讨Java编程语言中面向对象特性的教材。面向对象编程(Object-Oriented Programming, OOP)是现代软件开发中的核心编程范式,Java作为其代表之一,广泛应用于企业级应用、...

    Java面向对象编程指南

    在Java中,类是创建对象的蓝图,它们定义了对象的属性(数据成员)和行为(方法)。 在Java中,类的定义包括访问修饰符、类名、继承(如果有的话)以及类体。访问修饰符决定类、成员变量和方法的可见性。类名应遵循...

    Java就业培训教程.pdf

    9. **反射**:Java反射机制允许在运行时动态地获取类的信息并操作类的对象,包括创建对象、调用方法和访问字段。 10. **泛型**:泛型是Java SE 5.0引入的新特性,用于在编译时检查类型安全,同时提供更好的性能。它...

    Java基础尚硅谷宋红康学习笔记

    2. **类与对象**:Java是面向对象的语言,类是对象的模板,而对象是类的实例。类包含属性(成员变量)和方法(函数)。理解封装、继承和多态是Java面向对象编程的关键概念。 3. **数组与集合**:数组用于存储固定...

    JAVA SE(面向对象)学习课件

    对象则是类的实例,具有类定义的属性和方法。创建类的关键字是"class",而通过"new"关键字可以实例化一个对象。 2. 封装 封装是面向对象的三大特性之一,它隐藏了对象内部的实现细节,只暴露公共接口供外部访问。...

    【图文】Java面向对象特性.doc

    Java是一种广泛使用的面向对象编程语言,其面向对象的特性是其强大功能的核心所在。本文将深入探讨Java的面向对象特性,包括封装、继承、多态性以及接口等关键概念。 一、封装 封装是面向对象编程的基础,它指的是...

    java对接sds对象存储必备-应用与开发指南-完整版

    3. **元数据(Metadata)**: 元数据是关于对象的附加信息,分为系统定义的元数据(如大小、创建时间等)和用户定义的元数据(自定义属性)。 4. **访问域名(Endpoint)**: Endpoint是访问EOS服务的网络地址,用于构建...

    java图片附加水印源码

    在这个Java实现中,`WaterMarkUtil.java`很可能是核心类,它可能包含了添加水印的逻辑,包括创建一个`Graphics2D`对象,设置字体、颜色、透明度等属性,然后在原始图像上绘制水印。 3. **透明度设置**:在Java中,...

    一个漂亮的、使用样式与附加属性的WPF UI控件库

    附加属性则是一种特殊的依赖属性,它们可以被任何对象使用,而不仅仅是WPF控件,增加了灵活性和扩展性。 **PanuonUI.Silver-master** 从压缩包文件名来看,“PanuonUI.Silver-master”可能是该控件库的源代码仓库...

    Java Gossip(一)

    10. **反射**:Java反射API允许我们在运行时动态地获取类的信息(如类名、方法名、参数类型)并操作对象。 11. **泛型**:自Java 5引入,泛型提高了代码的类型安全性,允许在编译时检查类型,减少了强制类型转换的...

    面向对象程序设计课件(JAVA)

    Java是一种广泛使用的、跨平台的、面向对象的编程语言,它的设计目标是具有简单性、面向对象、健壮性、安全性、可移植性和高性能。 1. 封装:封装是面向对象的核心特征之一,它将数据和操作数据的方法捆绑在一起,...

    Java面向对象

    Java面向对象技术是Java编程语言的核心特性之一,它基于面向对象编程(Object-Oriented Programming,简称OOP)的理念,让代码设计更加清晰、模块化和易于维护。面向对象编程是一种编程范式,它将现实世界中的问题...

    JAVA语言程序设计补充材料及例题代码

    11. **反射**:Java反射机制允许在运行时动态访问和修改类的信息,如创建对象、调用方法、访问字段等。 12. **集合框架的新特性**:在Java 8及以上版本,集合框架增加了Lambda表达式、Stream API、Optional类等新...

    自考Java程序设计真题

    Java是一种面向对象的编程语言,具有继承、多态和封装等特点。Java的基本数据类型包括整数、浮点数、字符、布尔值等。Java的运算符包括算数运算符、比较运算符、逻辑运算符和赋值运算符等。 二、Java数组 Java数组...

Global site tag (gtag.js) - Google Analytics