Java最终域的值可以ps4改变dvd区域吗?

当final修饰一个数据域时,意义是声明该数据域是最终的,不可修改的。常见的使用场景就是eclipse自动生成的serialVersionUID一般都是final的。
另外还可以构造线程安全(thread safe)的immutable类,比如String,其数据域都是final的。这些使用场景都建立在final不可修改这个条件上,但是,反射可以打破这一切。
1.利用反射修改final数据域
首先,构造一个Person类,里面有个final字段NAME。我们尝试着修改这个字段。顺利的出乎意料。
public class Person {
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Person p = new Person();
Field field = p.getClass().getDeclaredField("NAME");
field.setAccessible(true);
field.set(p,"Hello");
System.out.println(field.get(p));
//p.printName();
private final String NAME = "Clive";
public Person() {
public void printName() {
System.out.println(NAME);
/***************
console print:
***************/
2.内联与内联消除
NAME数据域如此简单的就被修改了,final真是太"不安全了"! 但是,当我们调用p.printName() 时,控制台打印的却是"Clive"字符串。这是因为JVM做了优化处理, 当一个数据域被final修饰,那就表明这个数据域是常量,JVM会把所有NAME数据域出现的地方全部用"Clive"替换掉, 比如 printName() 方法其实被优化成了这样。
public void printName() { System.out.println("Clive"); }
所以,要想不被自动优化,就要把代码弄得复杂点,如下
public class Person {
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Person p = new Person();
Field field = p.getClass().getDeclaredField("NAME");
field.setAccessible(true);
field.set(p,"Hello");
System.out.println(field.get(p));
p.printName();
private final String NAME =(null!=null?"Clive":"Clive"); //声明时即初始化
public Person() {
//或者,在这里设置NAME数据域的值
//NAME="Clive";
public void printName() {
System.out.println(NAME);
/***************
console print:
***************/
结果见 console print,顺利消除了优化,final字段最终被修改了!
3.修改static final数据域
如果在NAME字段再增加一个static关键字修饰,然后再用反射修改的话就不行了, 会抛出异常
java.lang.IllegalAccessException: Can not set static final int field ...
这时,修改Field中的modifiers数据域,清除代表final的那个bit,才可以成功修改。
public class Person {
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Person p = new Person();
Field field = p.getClass().getDeclaredField("NAME");
Field modifiers = field.getClass().getDeclaredField("modifiers");
modifiers.setAccessible(true);
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);//fianl标志位置0
field.set(p,"Hello");
System.out.println(field.get(p));
p.printName();
private final String NAME =(null!=null?"Clive":"Clive");
public Person() {
public void printName() {
System.out.println(NAME);
/**************
console print:
**************/
这个知识点感觉知道就好,平时还是不要修改final数据域的好 :)
阅读(...) 评论()Java方法中形式参数的值改变为什么会同时改变成员变量的值? - 知乎有问题,上知乎。知乎作为中文互联网最大的知识分享平台,以「知识连接一切」为愿景,致力于构建一个人人都可以便捷接入的知识分享网络,让人们便捷地与世界分享知识、经验和见解,发现更大的世界。3被浏览683分享邀请回答21 条评论分享收藏感谢收起12 条评论分享收藏感谢收起写回答今天才发现用final修饰过的域是可以赋值的【java吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:715,064贴子:
今天才发现用final修饰过的域是可以赋值的收藏
初始化后就不可以改变了未初始化前是可以赋值的
如果初值都不能赋,那要他来干什么?
果真是J8er多,力量大。
貌似final修饰的域在初始化的时候不赋值程序就直接报错了啊
。。。。final修饰变量初始化必须赋值,不赋值报错。
一种东西叫“初始化” 还有一种叫“赋值” 楼主啊
你开始没有赋值。那当然可以在后面赋值。
好了,终结final的初步使用方法:1定义该域时初始化。2如果该域为非静态域可放在类的构造函数中初始化。3如果域为非静态域,可放在初始化块中初始化。final一经初始化,不可改变。
我前段时间刚看了thinging in java这种在域中定义的属于空白final,那么就需要在构造方法中对它进行赋值!
登录百度帐号Java中为什么改变了复制后的数组的值原数组里面的值也会被改变_百度知道
Java中为什么改变了复制后的数组的值原数组里面的值也会被改变
我有更好的答案
因为数组是一个对象也许楼主是做了类似这样的事int[] i1 = new int[10];int[] i2 = i1;这样的话i1和i2访问的是内存中的同一段数据,所以修改一个,另一个也跟着改变了想要不改变的话应该这样复制int[] i1 = new int[10];int[] i2 = new int[10];for(int i=0;i&i1.i++){i2[i]=i1[i];}每次new都会在内存中开辟一个新的空间,这样两个数组所访问的就不是同一地址了两个数组就可以独立操作了但是如果是一个复合引用类型的数组,即使用第二种方式复制,结果仍是修改一个,另一个跟着变
采纳率:60%
有值类型和引用类型,复制函数是引用类型做参数
是什么概念啊
8中简单类型都是值类型,如int、char、boolean等
懂了 谢谢啊
本回答被提问者采纳
复制的是引用
引用怎么解释,还是不怎么懂
为您推荐:
其他类似问题
您可能关注的内容
java的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。Java,列表框的值怎么修改?_百度知道
Java,列表框的值怎么修改?
我写了一个Swing,里面有一个JTextField,,一个JButton,一个JList。之前我在JList里设置了String[]数组,可以显示几个名称,然后我在按钮上定义了一个监听器,一按按钮就可以在actionPerformed()方法里修改列表框的值,我想问怎么修改JList的值,他没有setTex...
我有更好的答案
默认的JList不能编辑,要编辑的话要手动设置内部数据结构。最简单的方法是用DefaultListModelDefaultListModel listModel = new DefaultListModel();JList list = new JList(listModel);DefaultListModel 里面的一些方法: void
add(int index, Object element)
addElement(Object obj)
setElementAt(Object obj, int index)
removeElement(Object obj)
采纳率:44%
setSelectedIndexpublic void setSelectedIndex(int index)选择单个单元。 参数:index - 要选择的一个单元的索引public void setSelectedValue(Object anObject,
boolean shouldScroll)从列表中选择指定的对象。 参数:anObject - 要选择的对象shouldScroll - 如果所选对象存在,但列表需要滚动才能显示,则为 true;否则为 false
JList 的内容可以是动态的,换句话说,在创建 JList 之后,列表元素可以改变值,列表的大小也可以改变。JList 利用 swing.event.ListDataListener 实现在其模型中观察更改。正确实现的 ListModel 在每次发生更改时向其侦听器发出通知。更改的特征由标识已修改、已添加或已移除的列表索引范围的 swing.event.ListDataEvent 来描述。简单动态内容 JList 应用程序可以使用 DefaultListModel 类存储列表元素。此类实现 ListModel 接口,同时提供 java.util.Vector API。构造函数:List(ListModel dataModel)
构造一个 JList,使其使用指定的非 null 模型显示元素。也可以用方法:setModel(ListModel model)
设置表示列表内容或“值”的模型如下可以访问每一个元素并输出元素值, String[] data = {&one&, &two&, &three&, &four&}; JList dataList = new JList(data);
for(int i = 0; i & dataList.getModel().getSize(); i++) {
System.out.println(dataList.getModel().getElementAt(i)); }如果你想改列表中的元素,试试用(不过前提是用DefaultListModel,而不是String数组.)DefaultListModel 里面的一些方法: void add(int index, Object element)
在此列表的指定位置处插入指定元素。
void addElement(Object obj)
将指定组件添加到此类表的末尾。
int capacity()
返回此列表的当前容量。
void clear()
从此列表中移除所有元素。
boolean contains(Object elem)
测试指定对象是否为此类表中的组件。
void copyInto(Object[] anArray)
将此列表的组件复制到指定数组中。
Object elementAt(int index)
返回指定索引处的组件。
Enumeration&?& elements()
返回此列表的组件枚举。
void ensureCapacity(int minCapacity)
增加此列表的容量(如有必要),以确保其至少能够保存最小容量参数指定的组件数。
Object firstElement()
返回此列表中的第一个组件。
Object get(int index)
返回列表中指定位置处的元素。
Object getElementAt(int index)
返回指定索引处的组件。
int getSize()
返回此列表中的组件数。
int indexOf(Object elem)
搜索 elem 的第一次出现。
int indexOf(Object elem, int index)
从 index 开始搜索 elem 的第一次出现。
void insertElementAt(Object obj, int index)
将指定对象作为此列表中的组件插入到指定的 index 处。
boolean isEmpty()
测试此列表中是否有组件。
Object lastElement()
返回列表的最后一个组件。
int lastIndexOf(Object elem)
返回 elem 最后一次出现处的索引。
int lastIndexOf(Object elem, int index)
从指定的索引处开始反向搜索 elem,并返回该对象的索引。
Object remove(int index)
移除此列表中指定位置处的元素。
void removeAllElements()
从此列表中移除所有组件,并将它们的大小设置为零。
boolean removeElement(Object obj)
从此列表中移除参数的第一个(索引最小的)匹配项。
void removeElementAt(int index)
删除指定索引处的组件。
void removeRange(int fromIndex, int toIndex)
删除指定索引范围中的组件。
Object set(int index, Object element)
使用指定元素替换此列表中指定位置上的元素。
void setElementAt(Object obj, int index)
将此列表指定 index 处的组件设置为指定的对象。
void setSize(int newSize)
设置此列表的大小。
int size()
返回此列表中的组件数。
Object[] toArray()
以正确顺序返回包含此列表中所有元素的数组。
String toString()
返回显示并标识此对象的属性的字符串。
void trimToSize()
对此列表的容量进行裁剪,使其等于此列表的当前大小。
为您推荐:
其他类似问题
列表框的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。

我要回帖

更多关于 改变图像区域颜色 的文章

 

随机推荐