❶ java 可以动态创建 属性字段么
可以的,你用 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;
}
}
❷ java中的属性和C#中的字段有何练习和区别
C#里面的字段类似于Java中的属性,也可以把它叫做类的成员变量,在C#中,属性有特殊的含义。
在C#中,
public string aa;
aa就是字段,它不足的就是无法限制值的输入输出,
public string aa
{
get;
set;
}
这时的aa就是属性,它可以通过get来限制读取的值,比如如果对像为空,就NEW一个,
通过set可以有效的控制值的输入
set get 二者可为一个,也可以两个都有,只有get时就是只读,只有set时就是只写,通常是两都都有.
❸ java中类定义的属性是什么意思
java是面向对象编程的语言
什么叫对象?
publicclassPerson{
privatestringname;
}
什么叫类?
Person是定义了一个人的java类-----它是一类事物的统称
既然是人了,那就应该有名字吧,name就是person的一个属性,比如还有年龄啊,性别啊什么的
实例化对象---就是通过类(Person)具体拿到某一个人
比如Personp=newPerson("张三")
张三就是Person中具体的一个对象
这就是面相对象编程明白吧
❹ java中的字段和属性的区别
一个是变量(String s),一个是成员变量的属性(String name=user.getUsername())
字段可以有方法( s.equals(user.getUsername())
但是属性是字段的时候也可以有字段的方法
❺ java "字段"啥意思
public final static InputStream in = nullInputStream();
nullInputStream是这样实现的:
private static InputStream nullInputStream() throws NullPointerException {
if (currentTimeMillis() > 0)
return null;
throw new NullPointerException();
}
他不是返回null,就是抛出异常,如何初始化in呢?
解答:
看了一下java.lang.System的源代码.
System类里有大量的native方法,是调用本地代码的,这些代码很可能是由虚拟机来调用的.
System类的开头有一段:
static {
registerNatives();
}
这段代码会在虚拟机启动的时候就执行,它在虚拟机里注册System需要使用的一些本地代码
比如:
private static native Properties initProperties(Properties props);
private static native void setOut0(PrintStream out);
在windows下的话,它就告诉虚拟机到哪个dll文件里去找相应的实现
>然而,我知道out是一个PrintStream的对象,但我查看了有关的原代码:public final static PrintStream out = nullPrintStream();
>public final static InputStream in = nullInputStream();
在nullInputStream()方法里有注释解释为什么会设置为空:
/**
* The following two methods exist because in, out, and err must be
* initialized to null. The compiler, however, cannot be permitted to
* inline access to them, since they are later set to more sensible values
* by initializeSystemClass().
*/
private static InputStream nullInputStream() throws NullPointerException {
if (currentTimeMillis() > 0)
return null;
throw new NullPointerException();
}
也就说in, out, and err 初始化为null,然后会在后来由initializeSystemClass()方法类初始化成有意义的值
/**
* Initialize the system class. Called after thread initialization.
*/
private static void initializeSystemClass() {
props = new Properties();
initProperties(props);
sun.misc.Version.init();
FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
setIn0(new BufferedInputStream(fdIn)); !!!
setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true)); !!!
setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true)); !!!
// Enough of the world is now in place that we can risk
// initializing the logging configuration.
try {
java.util.logging.LogManager.getLogManager().readConfiguration();
} catch (Exception ex) {
// System.err.println("Can′t read logging configuration:");
// ex.printStackTrace();
}
// Load the zip library now in order to keep java.util.zip.ZipFile
// from trying to use itself to load this library later.
loadLibrary("zip");
// Subsystems that are invoked ring initialization can invoke
// sun.misc.VM.isBooted() in order to avoid doing things that should
// wait until the application class loader has been set up.
sun.misc.VM.booted();
}
in,out,err就是在以上方法以下三条语句里初始化的.
setIn0(new BufferedInputStream(fdIn)); !!!
setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true)); !!!
setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true)); !!!
看
private static native void setIn0(InputStream in);
~~~~~~~
这是个native函数,是前面registerNatives()的时候注册了的.这个函数应该是把实际连接到输入输出设备的句柄传给虚拟机并赋值给in,out,err
至于:
>InputStream是个抽象的类,怎么能使用char=(char)System.in.read()读入一个字符
我想你还没有明白什么是面向对象.
看看下面代码,我用OutputStream(也是抽象类,跟InputStream对应的输出类)以方便演示:
import java.io.IOException;
import java.io.OutputStream;
public class HelloWorld {
public OutputStream out=null;
public void setOutputStream(OutputStream out){
this.out=out;
}
public static void main(String[] args) throws IOException{
HelloWorld h=new HelloWorld();
PrintStream myOut=System.out;//System.out是一个PrintStream
h.setOutputStream(myOut);
h.out.write("hello,world".getBytes());//一般没人这么写的
}
}
以上代码执行后会输出hello,world
h.out是OutputStream,也是个抽象类,为什么能write(o)呢?
因为PrintStream是OutputStream的子类,所以能被"当作"OutputStream传给h.setOutputStream(myOut);
h.out.write执行的时候实际上是调用这个传进来的PrintStream实例的write方法
同样System.in和out肯定也是在initializeSystemClass()的时候被赋予了一个实际的可用的子类
要能体会到面向对象的好处,就要逐渐适应"对接口编程"的思想,相同接口的对象可以根据需要方便的替换.
比如,我刚才传了一个PrintStream,因此HelloWorld输出到了屏幕上. 我如果传给OutputStream的另一个子类FileOutputStream,就会输出到文件里
>还有为什么不是说字符流:writer和reader一般用于UniCode的读写吗?为什么键盘的输入用reader类呢?
不知道你在哪里看到说writer和reader一般用于UniCode的读写
❻ java 怎么定义属性
定义属性的语法格式如下:
[修饰符] 属性类型 属性名 [=默认值]
属性语法格式的详细说明如下:
1、修饰符:修饰符可以省略,也可以是public、protected、private、static、final,其中public、protected、private三个最多只能出现其中之一,可以与static、final组合起来修饰属性。
2、属性类型:属性类型可以是Java语言允许的任何数据类型,包括基本类型和现在介绍的引用类型。
3、属性名:属性名则只要是一个合法的标识符即可,但这只是从语法角度来说的;如果从程序可读性角度来看,属性名应该由一个或多个有意义的单词连缀而成,第一个单词首字母小写,后面每个单词首字母大写,其他字母全部小写,单词与单词之间不需使用任何分隔符。
4、默认值:定义属性还可以定义一个可选的默认值。
提示:属性是一种比较传统、也比较符合汉语习惯的说法,在Java的官方说法里,属性被称为Field,因此有的地方也把属性翻译为字段。
定义方法的语法格式如下:
[修饰符] 方法返回值类型 方法么(形参列表)
{
//由零条到多条可执行性语句组成的方法体
}
❼ java中字段是什么怎么定义字段字段是变量吗和变量 方法 属性有什么区别字段有返回值吗。。。
字段就是成员变量,注意是成员变量,不是局部变量。字段也就是属性了,一个类的属性。
只是叫法不同,java的API中一般叫成员变量就字段,有时也叫域。而我们一般的编程的时候,就字段叫成员变量
补------------
out就是一个字段,也就是是System类的一个成员变量。只不过个这成员变量是一个对象,也就是out是一个 PrintStream类的对象。这就是在一个类里执有其它类的对象的用法
❽ JAVA里的字段是什么意思
sm yisd什么字段?
❾ java中的属性是什么意思
属性就是 这个类定义的一个成员 变量 举个例子 就是一个人的胳膊和腿欢迎来我们的java世界ourjavasky 针对层次不同量身学习java技术 www.ourjavasky.cn
❿ Java中的属性和字段有什么区别
区别在于java中属性是要有get、set方法的,不是所有字段都有get、set方法