第十四行打印的是Field对象的modifiers的值,跟那个_isCreatePool有什么关系?掩耳盗铃?
System.out.println("修改后:"+Modifier.toString(this.getClass().getDeclaredField("_isCreatePool").getModifiers()));
System.out.println("修改后:"+Modifier.toString(this.getClass().getDeclaredField("_isCreatePool").getModifiers()));
解决方案 »
- java String.split(^}$)为什么不能用,超简单?!
- 泛型中T与?的区别
- 散尽可用分~~~~~~~~!!!!!!!!!!!!!!!!!!!!!!!
- JAVA输入输出流问题
- 哪位前辈有GUI设计得比较好的源码,可以共享一下,学习下,对于GUI设计实在不行
- java连接数据库的问题!!
- swing 作统计图的问题,有谁知道现成的工具??
- 一个关于NoClassDefFounderErr的问题2
- 大侠们:谁能教我JAVA 入门?不胜感激!!!!
- java获取数据库中的表名多了一个sys_config
- 根据绝对路径检测一个文件是否满足class文件标准
- 同学找我做一个小项目,我报多少钱合适
第一点:我做个实验试试
第二点:这是设计的一个方式问题,final , 是因为我已经 public ! 这是我想要final的原因!而不是setter !
第三点:是您自己的观点或估计,还是既成事实 ?我想知道,有否证明 !
NoSuchFieldException, IllegalAccessException {
MainTest m = new MainTest();
System.out.println("这是_isCreatePool被改变之前的值:" + m._isCreatePool);
m._isCreatePool = true;
m.test(m._isCreatePool);
m._isCreatePool = false;
System.out.println((m._isCreatePool) ? "没改变,依然是true"
: "值被改变了,说明反射字符_isCreatePool,将_isCreatePool的修饰符改为final失败了,无效,此时,结果由true为false");
m.check();// 这里增加一个方法,再次检测
} // 这里增加一个方法,再次检测
public void check() throws SecurityException, NoSuchFieldException {
Field _isCreatePoolField = this.getClass().getDeclaredField("_isCreatePool");
System.out.println("再次检测:" + Modifier.toString(_isCreatePoolField.getModifiers()));
}最后返回还是Public,感觉应该是修改final有作用域的。
部分核心Security检测的代码没有给源码,不好瞎说。不是说有了反射,就一定要破坏类的方位权限、作用域,而且你钻的还挺深的。
兄弟,别太钻牛角尖哈~
这又是对Java 基础了解不深引起的。你在m.test(m._isCreatePool) ; 后加上System.out.println(Modifier.toString(m.getClass().getField("_isCreatePool").getModifiers())); 测试下。
保证你有惊奇的发现;其实,你只要了解下JVM的类加载机制就知道了;
简单说是,在一个类加载器中,类只会加载一次,也就是你的JVM内存中还是原来的类的类型信息;所以你上面修改_isCreatePool的访问修饰符,而不重新编译加载新类,和你改了一个类不重新编译再运行,有什么区别;
* Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/package sun.reflect;import java.lang.reflect.Field;
import java.lang.reflect.Modifier;class UnsafeFieldAccessorFactory {
static FieldAccessor newFieldAccessor(Field field, boolean override) {
Class type = field.getType();
boolean isStatic = Modifier.isStatic(field.getModifiers());
boolean isFinal = Modifier.isFinal(field.getModifiers());
boolean isVolatile = Modifier.isVolatile(field.getModifiers());
boolean isQualified = isFinal || isVolatile;
boolean isReadOnly = isFinal && (isStatic || !override);
if (isStatic) {
// This code path does not guarantee that the field's
// declaring class has been initialized, but it must be
// before performing reflective operations.
UnsafeFieldAccessorImpl.unsafe.ensureClassInitialized(field.getDeclaringClass()); if (!isQualified) {
if (type == Boolean.TYPE) {
return new UnsafeStaticBooleanFieldAccessorImpl(field);
} else if (type == Byte.TYPE) {
return new UnsafeStaticByteFieldAccessorImpl(field);
} else if (type == Short.TYPE) {
return new UnsafeStaticShortFieldAccessorImpl(field);
} else if (type == Character.TYPE) {
return new UnsafeStaticCharacterFieldAccessorImpl(field);
} else if (type == Integer.TYPE) {
return new UnsafeStaticIntegerFieldAccessorImpl(field);
} else if (type == Long.TYPE) {
return new UnsafeStaticLongFieldAccessorImpl(field);
} else if (type == Float.TYPE) {
return new UnsafeStaticFloatFieldAccessorImpl(field);
} else if (type == Double.TYPE) {
return new UnsafeStaticDoubleFieldAccessorImpl(field);
} else {
return new UnsafeStaticObjectFieldAccessorImpl(field);
}
} else {
if (type == Boolean.TYPE) {
return new UnsafeQualifiedStaticBooleanFieldAccessorImpl(field, isReadOnly);
} else if (type == Byte.TYPE) {
return new UnsafeQualifiedStaticByteFieldAccessorImpl(field, isReadOnly);
} else if (type == Short.TYPE) {
return new UnsafeQualifiedStaticShortFieldAccessorImpl(field, isReadOnly);
} else if (type == Character.TYPE) {
return new UnsafeQualifiedStaticCharacterFieldAccessorImpl(field, isReadOnly);
} else if (type == Integer.TYPE) {
return new UnsafeQualifiedStaticIntegerFieldAccessorImpl(field, isReadOnly);
} else if (type == Long.TYPE) {
return new UnsafeQualifiedStaticLongFieldAccessorImpl(field, isReadOnly);
} else if (type == Float.TYPE) {
return new UnsafeQualifiedStaticFloatFieldAccessorImpl(field, isReadOnly);
} else if (type == Double.TYPE) {
return new UnsafeQualifiedStaticDoubleFieldAccessorImpl(field, isReadOnly);
} else {
return new UnsafeQualifiedStaticObjectFieldAccessorImpl(field, isReadOnly);
}
}
} else {
if (!isQualified) {
if (type == Boolean.TYPE) {
return new UnsafeBooleanFieldAccessorImpl(field);
} else if (type == Byte.TYPE) {
return new UnsafeByteFieldAccessorImpl(field);
} else if (type == Short.TYPE) {
return new UnsafeShortFieldAccessorImpl(field);
} else if (type == Character.TYPE) {
return new UnsafeCharacterFieldAccessorImpl(field);
} else if (type == Integer.TYPE) {
return new UnsafeIntegerFieldAccessorImpl(field);
} else if (type == Long.TYPE) {
return new UnsafeLongFieldAccessorImpl(field);
} else if (type == Float.TYPE) {
return new UnsafeFloatFieldAccessorImpl(field);
} else if (type == Double.TYPE) {
return new UnsafeDoubleFieldAccessorImpl(field);
} else {
return new UnsafeObjectFieldAccessorImpl(field);
}
} else {
if (type == Boolean.TYPE) {
return new UnsafeQualifiedBooleanFieldAccessorImpl(field, isReadOnly);
} else if (type == Byte.TYPE) {
return new UnsafeQualifiedByteFieldAccessorImpl(field, isReadOnly);
} else if (type == Short.TYPE) {
return new UnsafeQualifiedShortFieldAccessorImpl(field, isReadOnly);
} else if (type == Character.TYPE) {
return new UnsafeQualifiedCharacterFieldAccessorImpl(field, isReadOnly);
} else if (type == Integer.TYPE) {
return new UnsafeQualifiedIntegerFieldAccessorImpl(field, isReadOnly);
} else if (type == Long.TYPE) {
return new UnsafeQualifiedLongFieldAccessorImpl(field, isReadOnly);
} else if (type == Float.TYPE) {
return new UnsafeQualifiedFloatFieldAccessorImpl(field, isReadOnly);
} else if (type == Double.TYPE) {
return new UnsafeQualifiedDoubleFieldAccessorImpl(field, isReadOnly);
} else {
return new UnsafeQualifiedObjectFieldAccessorImpl(field, isReadOnly);
}
}
}
}
}
您说不是反射,那么请问,您这里,是怎么处理呢?求教上面给你说了下 要去了解类加载机制;你若了解 Java中的对象拷贝原理,结合上面的说的,应该是完全明白了;其实就是这条语句:
Field _isCreatePoolField = this.getClass().getDeclaredField("_isCreatePool") ;
返回的是Field对象的一个副本,你怎么改都不会影响原来的对象;
您说不是反射,那么请问,您这里,是怎么处理呢?求教上面给你说了下 要去了解类加载机制;你若了解 Java中的对象拷贝原理,结合上面的说的,应该是完全明白了;其实就是这条语句:
Field _isCreatePoolField = this.getClass().getDeclaredField("_isCreatePool") ;
返回的是Field对象的一个副本,你怎么改都不会影响原来的对象;1、类加载器,在我现在的思维里,无非就是类被初始调度时,赋值而已,不知理解错了么?
2、你说现在改变的是副本,那要怎么才能拿到原来的对象 ?
1、 要你去了解 JVM 的类加载机制,是因为这个过程会产生一个表示加载类的一个Class对象,而 反射 获取就是这些 Class实例 表示的 类的信息;
若自己确实想学习,从这里就可以去了解虚拟机的执行子系统,虚拟机的内存结构,虚拟机的内存管理机制 等内容了;
2、通过Java API拿不到Field原来的对象;所有Class.getFields(), Class.getField(String), Class.getDeclaredFields(), Class.getDeclaredField(String)都是返回Field的 copy对象;为什么,源代码就是这么写的;(为啥不把源代码贴出来,自己把JDK下的那个src.zip 导入,就可以自己看了);
上面提到了Java中对象的copy机制,若也想学习,就可以去了解下什么是深拷贝、浅拷贝;
1、 要你去了解 JVM 的类加载机制,是因为这个过程会产生一个表示加载类的一个Class对象,而 反射 获取就是这些 Class实例 表示的 类的信息;
若自己确实想学习,从这里就可以去了解虚拟机的执行子系统,虚拟机的内存结构,虚拟机的内存管理机制 等内容了;
2、通过Java API拿不到Field原来的对象;所有Class.getFields(), Class.getField(String), Class.getDeclaredFields(), Class.getDeclaredField(String)都是返回Field的 copy对象;为什么,源代码就是这么写的;(为啥不把源代码贴出来,自己把JDK下的那个src.zip 导入,就可以自己看了);
上面提到了Java中对象的copy机制,若也想学习,就可以去了解下什么是深拷贝、浅拷贝;恩 !可能您误会我的意思了 。
1、类加载,必然是在调度时候才加载,只是rt.jar等等在固定目录的文件中的class才会被提前加载。
我刚刚指的是:final除了在定义时候可以被赋值,还可以在定义不赋值,而在构造器中赋值,所以我才所说【无非就是类被初始调度时,赋值而已】 。
但是,我不理解的是,您说【除了反射,还是能直接改的 】!
2、clone的话,我不是常用,因为我目前很少用到它,我用到它的场景不多,对于何种场景被用到不熟悉,所以,请指教!