-
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><<希望你参考下>></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><<希望你参考下>></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个答案 按时间排序 按投票排序
-
通过程序修改 .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); } }
2011年3月28日 16:56
-
读取类:
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
相关推荐
在Java中,我们通过定义类(Class)来实现封装,类是对象的模板,它包含了属性(Fields,即数据成员)和方法(Methods,即行为)。我们可以通过访问修饰符(public, private, protected)来控制属性和方法的可见性,...
2. **封装**:封装是面向对象编程的基础原则之一,通过封装,我们可以隐藏对象的内部实现细节,只暴露必要的接口给外部使用。在Java中,我们使用访问修饰符(如private, public, protected)来控制类的成员对外的...
Java语言的动态属性是其灵活性和可扩展性的关键特性之一,允许程序在运行时检查、修改和调用类的属性和方法。以下是对这些概念的详细说明: 1. **Java.lang.Class**: 这个类提供了关于Java类的元数据信息,如构造...
**Java面向对象编程基础** Java是一种广泛使用的编程语言,以其“一次编写,到处运行”的特性闻名,尤其在企业级应用开发中占据主导地位。面向对象编程(Object-Oriented Programming,OOP)是Java的核心概念,它...
一个类可以用来创建多个对象实例,这些对象共享相同的属性定义,但每个对象的具体属性值可以不同。 2. **当运行javac命令对一个java源程序进行编译时,必须写出该源程序文件的完整文件名,包括扩展名.java。(T)**...
《Java面向对象程序设计》是一本深入探讨Java编程语言中面向对象特性的教材。面向对象编程(Object-Oriented Programming, OOP)是现代软件开发中的核心编程范式,Java作为其代表之一,广泛应用于企业级应用、...
在Java中,类是创建对象的蓝图,它们定义了对象的属性(数据成员)和行为(方法)。 在Java中,类的定义包括访问修饰符、类名、继承(如果有的话)以及类体。访问修饰符决定类、成员变量和方法的可见性。类名应遵循...
9. **反射**:Java反射机制允许在运行时动态地获取类的信息并操作类的对象,包括创建对象、调用方法和访问字段。 10. **泛型**:泛型是Java SE 5.0引入的新特性,用于在编译时检查类型安全,同时提供更好的性能。它...
2. **类与对象**:Java是面向对象的语言,类是对象的模板,而对象是类的实例。类包含属性(成员变量)和方法(函数)。理解封装、继承和多态是Java面向对象编程的关键概念。 3. **数组与集合**:数组用于存储固定...
对象则是类的实例,具有类定义的属性和方法。创建类的关键字是"class",而通过"new"关键字可以实例化一个对象。 2. 封装 封装是面向对象的三大特性之一,它隐藏了对象内部的实现细节,只暴露公共接口供外部访问。...
Java是一种广泛使用的面向对象编程语言,其面向对象的特性是其强大功能的核心所在。本文将深入探讨Java的面向对象特性,包括封装、继承、多态性以及接口等关键概念。 一、封装 封装是面向对象编程的基础,它指的是...
3. **元数据(Metadata)**: 元数据是关于对象的附加信息,分为系统定义的元数据(如大小、创建时间等)和用户定义的元数据(自定义属性)。 4. **访问域名(Endpoint)**: Endpoint是访问EOS服务的网络地址,用于构建...
在这个Java实现中,`WaterMarkUtil.java`很可能是核心类,它可能包含了添加水印的逻辑,包括创建一个`Graphics2D`对象,设置字体、颜色、透明度等属性,然后在原始图像上绘制水印。 3. **透明度设置**:在Java中,...
附加属性则是一种特殊的依赖属性,它们可以被任何对象使用,而不仅仅是WPF控件,增加了灵活性和扩展性。 **PanuonUI.Silver-master** 从压缩包文件名来看,“PanuonUI.Silver-master”可能是该控件库的源代码仓库...
10. **反射**:Java反射API允许我们在运行时动态地获取类的信息(如类名、方法名、参数类型)并操作对象。 11. **泛型**:自Java 5引入,泛型提高了代码的类型安全性,允许在编译时检查类型,减少了强制类型转换的...
Java是一种广泛使用的、跨平台的、面向对象的编程语言,它的设计目标是具有简单性、面向对象、健壮性、安全性、可移植性和高性能。 1. 封装:封装是面向对象的核心特征之一,它将数据和操作数据的方法捆绑在一起,...
Java面向对象技术是Java编程语言的核心特性之一,它基于面向对象编程(Object-Oriented Programming,简称OOP)的理念,让代码设计更加清晰、模块化和易于维护。面向对象编程是一种编程范式,它将现实世界中的问题...
11. **反射**:Java反射机制允许在运行时动态访问和修改类的信息,如创建对象、调用方法、访问字段等。 12. **集合框架的新特性**:在Java 8及以上版本,集合框架增加了Lambda表达式、Stream API、Optional类等新...
Java是一种面向对象的编程语言,具有继承、多态和封装等特点。Java的基本数据类型包括整数、浮点数、字符、布尔值等。Java的运算符包括算数运算符、比较运算符、逻辑运算符和赋值运算符等。 二、Java数组 Java数组...