throwable怎么读,java基础都有那些?
throwable怎么读,java基础都有那些?详细介绍
本文目录一览: throw怎么读
throw 英[θr??] 美[θro]
vi. 投掷;丢;抛
n. 投掷的距离;丢
vt. 掷(色子);抛;猛动(头、臂、腿);使处于,使限于
[例句]My boys love to throw things.
我的几个儿子爱扔东西。
英 [θr??]
美 [θro?]
vi. 投掷; 丢; 抛
n. 投掷的距离; 丢
vt. 掷(色子); 抛; 猛动(头、臂、腿); 使处于,使限于
网 络
传球;
扔;
投;
投掷
过去式: threw
过去分词: thrown
现在分词: throwing
第三人称单数: throws
派生词:throwable thrower
1. I can't seem to throw off this feeling of inertia. 更多牛津
我好像无法摆脱这种无力的感觉。
来自《权威词典》
2. The public are requested not to throw waste paper in the park.
公众被要求不得在公园里乱扔废纸。
来自《简明英汉词典》
3. The thief managed to throw his pursuers off the scent.
小偷终于把追踪者甩掉了。
来自《简明英汉词典》
4. Throw him into the dungeon and leave him there.
把他扔进地牢,让他呆在那儿。
来自《简明英汉词典》
5. Just the thought of eating snakes makes me want to throw up.
只要一想到吃蛇,我就想呕吐。
来自《简明英汉词典》
Throwable怎么读啊 java里的所有的子类啊
Throwable是java.lang包中一个专门用来处理异常的类。它有两个子类,即Error 和Exception,它们分别用来处理两组异常。
eclipse里面有一个功能叫查看继承层次,快捷键是ctrl + t
Java 异常结构
异常时程序运行过程中产生的错误。
异常处理框架时java语言健壮性的一个重要体现。
Java把异常当做对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。
在java API中已定义了许多异常类,这些异常类分为两大类,错误类Error和异常Exception。
Java异常体系结构呈树状,其层次结构如图:
Thorwable类所有异常和错误的超类,有两个子类Error和exception,分别表示错误和异常。
其中异常类Exception又分为运行时异常(RuntimeException)和检查异常(Checked Exception)。
两者的区别:
Error和Exception
Error是程序无法处理的错误,比如OutOfMemoryError、ThreadDeath等。这些异常发生时,java虚拟机(JVM)一般会选择线程终止。
Exception是程序本身可以处理的异常,这种异常分两大类:运行时异常和非运行时异常。程序中应当尽可能去处理这些异常。
运行时异常和非运行时异常
运行时异常都是RuntimeException类及其子类异常,如NullPointerException、IndexOutOfBoundsException等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是有程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
非运行时异常是RuntimeException以外的异常,类型上属于Exception类及其子类。从程序角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下自定义检查异常。
暗黑破坏神2 V1.12 怎么用UdieToo修改加爆率的装备?
1、打开。
首先确保你的机子上安装了《暗黑破坏神II》V1.10B14版本的!然后把下载好的修改器解压出来,放在任意位置,然后双击打开(+_+!这不是废话么)。
2、进入。
确保你的暗黑上有人物存档(就是新建的人物),选中、点右下角的OK。
3、人物属性的编辑。
由于更新成110以后,人物的属性都有了上限。例如:生命法力上限是8191。基本属性(如力量)是1023。技能等级99(但最高能改20,我晕)。人物等级只能通过经验来修改,99的经验好象是3522000000。编辑方法:点击属性的数字,修改!这里特别注意一下:由于上限的限制!一旦你编辑的数值超过上限,游戏就会把你所添的数字重置为减去上限值。例如你把力量改成1300,进游戏后就会变成1300-1024=76
4、任务的编辑
点击查看->任务(快捷键Q)把下边的2进制编码全部改成1即可通关(注意只能是1或0)。全部改0即可变为未完成的任务。
5、传送点的编辑。
将前边的方格点上即可激活。
1、装备的生成。
按快捷键S从里边拿出自己想要编辑的装备。
上边的红圈表示防具,前边那个是武器,绿圈是魔法和任务物品,最后的兰色的是套装。2。编辑物品。
把光标放到装备上,右键->编辑。这里是最关键的,由于游戏读取的是2进制编码,所以这里的修改就比较麻烦
黄色框:属性的名字。
绿色框:10进制数字(可修改)
红色框:快捷键
黄色框:属性的名字。
绿色框:10进制数字(可修改)
红色框:快捷键
左1、清除物品的修饰词(即:装备的基础类型。例:黄色,暗金,绿色...)。
左2、清除物品上的属性。
左3、是否允许打孔。
左4-8、未定义。
Chance Of Getting Magic Items % 获得属性装备
Extra Gold From Monsters % 怪掉的钱增加 (没什么用,改几个装备一卖就不缺钱了)
Add experience 增加百分比得到的经验值
All Skill Levels 增加所有技能 (这个是最nb的)
这些最好就是都打在一个小护身符上 用着虐怪很爽
UdieToo支持1.12吗,貌似一直就没更新过,
而且修改就失去乐趣了,
1、打开。
首先确保你的机子上安装了《暗黑破坏神II》V1.10B14版本的!然后把下载好的修改器解压出来,放在任意位置,然后双击打开(+_+!这不是废话么)。
2、进入。
确保你的暗黑上有人物存档(就是新建的人物),选中、点右下角的OK。
3、人物属性的编辑。
由于更新成110以后,人物的属性都有了上限。例如:生命法力上限是8191。基本属性(如力量)是1023。技能等级99(但最高能改20,我晕)。人物等级只能通过经验来修改,99的经验好象是3522000000。编辑方法:点击属性的数字,修改!这里特别注意一下:由于上限的限制!一旦你编辑的数值超过上限,游戏就会把你所添的数字重置为减去上限值。例如你把力量改成1300,进游戏后就会变成1300-1024=76
4、任务的编辑
点击查看->任务(快捷键Q)把下边的2进制编码全部改成1即可通关(注意只能是1或0)。全部改0即可变为未完成的任务。
5、传送点的编辑。
将前边的方格点上即可激活。
1、装备的生成。
按快捷键S从里边拿出自己想要编辑的装备。
上边的红圈表示防具,前边那个是武器,绿圈是魔法和任务物品,最后的兰色的是套装。2。编辑物品。
把光标放到装备上,右键->编辑。这里是最关键的,由于游戏读取的是2进制编码,所以这里的修改就比较麻烦
黄色框:属性的名字。
绿色框:10进制数字(可修改)
红色框:快捷键
黄色框:属性的名字。
绿色框:10进制数字(可修改)
红色框:快捷键
左1、清除物品的修饰词(即:装备的基础类型。例:黄色,暗金,绿色...)。
左2、清除物品上的属性。
左3、是否允许打孔。
左4-8、未定义。
右1、物品的属性。
右2、神符之语物品。
右3、魔法物品前缀词(蓝色)。
右4、魔法物品后缀词(蓝色)。
右5、魔法物品前缀词(金色)。
右6、魔法物品后缀词(金色)。
右7、暗金物品。
装备的修改2
1、属性的添加和去除。
点击右边的一个属性,光标就会变成一个魔棒,然后再往装备上点一下,OK添加成功!如果不想要就点清除属性。或者把这项属性的值设置为0。
2、属性值的修改。
大家注意到左边的那些1011010101没有,那里其实就是修改属性的最主要部分。当添加一个属性的时候左边就会多出2-4个字段,一个是属性ID,另外1-3个是数值设置。下边给大家看看如何添加“力量”这个属性。
从右边的属性框里选取Strength这个属性点到装备上。然后在下边的2进制编码中查找。
那个红色的表示属性ID,0就是力量。
绿色的是具体数值。可以修改,修改方法为:点击上边绿框下边的那个0进行修改。
3、物品的基础属性修改。
想不想让自己的装备即是无形而又不被损坏呢?想不想给自己的物品个性化一个很酷的名字呢?这里然后是是否为无形物品。1为是,0为否就告诉你怎么改。首先是物品是否为辩识好的。1为辩识过的,0为未辩识
接着是给装备加上一个自己定义的名字。1表示有名字,0表示没有。
特别注意:当改成1的时候需要清理一下物品的属性(点第2个方格)因为他会添加一个字符串,影响到你物品上的属性,所以最好是先把物品的基础做好后再加入其他属性。
最后是如何改成无法破坏的,方法有两个:1改耐久。2添加一个无法破坏属性。
改耐久的方法:找到MAX Dur这个字段改成0就可以无法破坏了,注意也要清理一下属性!
UdieToo中文属性对照表
Strength 增加力量
Energy 增加精力
Dexterity 增加敏捷
Vitality 增加体力
Stat Points 没用
Skill Points 没用
Life 没用
Max Life 增加最大生命
Mana 没用
Max Mana 增加最大魔法
stamina 没用
Max Stamina 没用
level 没用
experience 没用
gold 没用
goldbank 没用
Enhanced Defense % 防御增加百分比
Enchanced Damage % 伤害增加百分比
Enchanced Min Dmg % 增加最小伤害百分比
Attack Rating 增加命中率
Chance of Blocking % 增加格挡率
Min 1-handed Dmg 增加单手最小伤害
Max 1-handed Dmg 增加单手最大伤害
Min 2-handed Dmg 增加双手最小伤害
Max 2-handed Dmg 增加双手最大伤害
Damage % nv 伤害增加百分比Regenerate Mana % nv 法力再生
Regenerate Mana Plus % 法力再生(隐藏)
Heal Stemina Plus % 耐力恢复
lastexp 没用
nextexp 没用
Defense 增加防御
Def vs Missile 增加对近战的防御
Def vs Melee 增加对远程攻击的防御
Damage Reduced By 伤害减少
Magic Dmg Reduced By 魔法伤害减少
Damage Reduced By % 伤害减少百分比
Magic Resistance % 魔法抵抗百分比
Max Magic Resistance % 百分比增加最大魔法抵抗的百分比
Fire Resistance % 增加火抗的百分比
Max Fire Resistance % 增加最大火抗的百分比
Lightning Resistance % 增加电抗的百分比
Max Lightning Resistance % 增加最大电抗的百分比
Cold Resistance % 增加冰抗的百分比
Max Cold Resistance % 增加最大冰抗的百分比
Poison Resistance % 增加毒抗的百分比
Max Poison Resistance % 增加最大毒抗的百分比
damageaura 没用
Fire Damage 增加火焰伤害
Max Fire Damage 增加火焰伤害最大值
Lightning Damage 增加闪电伤害
Max Lightning Dmg 增加闪电伤害最大值
Magic Damage 增加魔法伤害
Max Magic Damage 增加魔法伤害最大值
Cold Damage 增加寒冷伤害
Max Cold Damage 增加寒冷伤害最大值
Cold Length 冻结目标的时间
Poison Damage 增加毒伤害
Max Poison Dmg 增加毒伤害最大值
Poison Length 目标中毒的持续时间
Life Stolen Per Hit Min 没用
Life Stolen Per Hit Max 偷取生命
Mana Stolen Per Hit Min 没用
Mana Stolen Per Hit Max 偷取法力
Stamina Drain Min 没用
Stamina Drain Max 没用
Stun Length 使目标眩晕的时间
Run/Walk Speed % nv 跑步速率增加百分比(隐藏)
Attack Speed % nv 攻击速率增加百分比(隐藏)
other_animrate 没用
quantity 没用
value 没用
Durabilty 没用
Max Durability 增加装备耐久
Replenish Life 自行恢复生命值
Max Durability % 没用
Life % 增加生命上限%
Mana % 增加法力上限%
Attacker Takes Damage Of 反伤
Extra Gold From Monsters % 怪掉的钱增加
Chance Of Getting Magic Items % 这个就是**
Knock Back 击退
Time Duration (未测试)
Add Class Skill 加单人技能
Unsentparam1 未知属性1
Add experience 增加百分比得到的经验值
Heal after kill 加X生命在杀死一只怪物后
Reduced prices 降低商人价格%
Double Herb Duration (未测试)
Light Radius 增加光照范围
Light Color nv 光照范围(隐藏)
Requirements % 物品对基本属性的需求
Level Require 没用
Increased Attack Speed 提升攻击速度%
Level Require % 增加等级需求
Last block frame 格挡有关
Faster Run/Walk 提升跑步速度%Non Class skill 无职业限制技能
state 特殊状态,比如头上永远顶个经验祭坛
Faster Hit Recovery Rate 加快打击恢复
Monster player count 没用
Poison override 没用
Faster Block Rate 快速格挡速度
Bypass undead 没用
Bypass demons 没用
Faster Cast Rate 快速释法速度
Bypass beasts 没用
Single Skill 增加职业限制技能
Rest in peace 杀死怪物后恢复平静
Curse resistance 抗诅咒几率
Poison Length Reduced By % 自己的中毒时间减少
Damage 增加伤害
Hit Causes Monster To Flee % 使怪物怪物会逃跑
Hit Blinds Target 打中的敌人会失明
Damage To Mana % 受损生命转化为提高法力
Ignore Target Defense 无视目标防御
Target Defense % 减少目标防御%
Prevent Monster Heal 防止怪物回血
Half Freeze Duration 自己的冰冻时间减半
Bonus To Attack Rating % 增加百分比额外的命中率
Reduce Monster Defense per Hit 每次打中都减少怪物的防御
Damage To Demons % 增加对恶魔系怪物的伤害
Damage To Undead % 增加对不死系怪物的伤害
Attack Rating Against Demons 增加对恶魔系怪物的命中率
Attack Rating Against Undead 增加最不死系怪物的命中率
Throwable (未测试)
Elemental Skill 增加火焰技能
All Skill Levels 增加所有技能
Attacker Takes Lightning Dmg Of 攻击者受到电伤害
ironmaiden_level 没用
lifetap_level 没用
thorns_percent 没用
bonearmor 没用
bonearmormax 没用
Attack Freezes Target 冻结目标
Chance of Open Wounds 撕开伤口的几率
Chance of Crushing Blow 压碎攻击的几率
Kick Damage 增加脚踢伤害
Mana After Each Kill 加法力在杀死一只怪物后
Life After Each Demon Kill 加生命在杀死恶魔系怪物后
Extra Blood 没用
Chance of Deadly Strike 致命攻击的几率Fire Absorbs % 火焰吸收%
Fire Absorbs 火焰吸收
Lightning Absorbs % 闪电吸收%
Lightning Absorbs 闪电吸收
Magic Absorbs % 魔法吸收%
Magic Absorbs 魔法吸收
Cold Absorbs % 冰冷吸收%
Cold Absorbs 冰冷吸收
Slows Target By % 使目标减缓%
Aura 灵气赐予
Indestructible 装备无法破坏
Cannot be Frozen 不会被冻结
Slower Stamina Drain % 没什么用
ReAnimate 杀死怪物后复活为
Pierce Attack % 穿透攻击
Fire Magic Arrows or Bolts 射出魔法箭
Fire Explosive Arrows or Bolts 射出爆炸箭
Min Throw Dmg nv 增加百分比最小远程攻击
Max Throw Dmg nv 增加百分比最大远程攻击
有时候修改完了不能游戏 其实你完全可以下个存档去玩 还省事
暗黑2老鸟的进
楼主,确实是很新的鸟,这个修改器不是这样用的。
不好好学习的下场,游戏都不会玩。。。
哥们有才............
反正我看不懂好多东西也改不掉.........
玩了好几年暗黑了建议去下个变态存档然后用修改器把物品移出来
我就是这么搞的
暗黑破坏神110修改器UdieToo简介
由于110版暗黑没中文修改器,所以只能使用老外制作的这个鸟语版的(-_-)!这款修改器的原理是在启动了游戏程序的基础上进行文件编辑的,所以想汉化是不太容易的的。
1、打开。
首先确保你的机子上安装了《暗黑破坏神II》V1.10B14版本的!然后把下载好的修改器解压出来,放在任意位置,然后双击打开(+_+!这不是废话么)。
2、进入。
确保你的暗黑上有人物存档(就是新建的人物),选中、点右下角的OK。
3、人物属性的编辑。
由于更新成110以后,人物的属性都有了上限。例如:生命法力上限是8191。基本属性(如力量)是1023。技能等级99(但最高能改20,我晕)。人物等级只能通过经验来修改,99的经验好象是3522000000。编辑方法:点击属性的数字,修改!这里特别注意一下:由于上限的限制!一旦你编辑的数值超过上限,游戏就会把你所添的数字重置为减去上限值。例如你把力量改成1300,进游戏后就会变成1300-1024=76
4、任务的编辑
点击查看->任务(快捷键Q)把下边的2进制编码全部改成1即可通关(注意只能是1或0)。全部改0即可变为未完成的任务。
5、传送点的编辑。
将前边的方格点上即可激活。
补充:改99技能的方法。网上下载一个Winhex。
方法:用hex打开你的人物存档(注意!存档文件是指那个以你人物名字开头,扩展名为d2s的那个!例如:Test.d2s)。 晕噢!全是16进制编码,看不懂吧~~嘿嘿!别急,在里边找第一个4A4D ,然后往前数60个数,有个69 66 ,找到后把69 66 后边的编码改成63 63 63 63 63......一直到4A4D前边为止!注意这个要特别小心,别出错!
然后进游戏吧!你可能当时就跟我急了:改坏了!进不了游戏了! 别着急!用UdieToo打开你的人物,然后什么都不用动直接点保存!再进游戏把!哈哈!所有技能均99级!
1、装备的生成。
按快捷键S从里边拿出自己想要编辑的装备。
上边的红圈表示防具,前边那个是武器,绿圈是魔法和任务物品,最后的兰色的是套装。
2、编辑物品。
把光标放到装备上,右键->编辑。这里是最关键的,由于游戏读取的是2进制编码,所以这里的修改就比较麻烦
黄色框:属性的名字。
绿色框:10进制数字(可修改)
红色框:快捷键
黄色框:属性的名字。
绿色框:10进制数字(可修改)
红色框:快捷键
左1。清除物品的修饰词(即:装备的基础类型。例:黄色,暗金,绿色...)。
左2。清除物品上的属性。
左3。是否允许打孔。
左4-8。未定义。
右1。物品的属性。
右2。神符之语物品。
右3。魔法物品前缀词(蓝色)。
右4。魔法物品后缀词(蓝色)。
右5。魔法物品前缀词(金色)。
右6。魔法物品后缀词(金色)。
右7。暗金物品。
装备的修改2
1、属性的添加和去除。
点击右边的一个属性,光标就会变成一个魔棒,然后再往装备上点一下,OK添加成功!如果不想要就点清除属性。或者把这项属性的值设置为0。
2、属性值的修改。
大家注意到左边的那些1011010101没有,那里其实就是修改属性的最主要部分。当添加一个属性的时候左边就会多出2-4个字段,一个是属性ID,另外1-3个是数值设置。下边给大家看看如何添加“力量”这个属性。
从右边的属性框里选取Strength这个属性点到装备上。然后在下边的2进制编码中查找。
那个红色的表示属性ID,0就是力量。
绿色的是具体数值。可以修改,修改方法为:点击上边绿框下边的那个0进行修改。
3、物品的基础属性修改。
想不想让自己的装备即是无形而又不被损坏呢?想不想给自己的物品个性化一个很酷的名字呢?这里然后是是否为无形物品。1为是,0为否就告诉你怎么改。首先是物品是否为辩识好的。1为辩识过的,0为未辩识
接着是给装备加上一个自己定义的名字。1表示有名字,0表示没有。
特别注意:当改成1的时候需要清理一下物品的属性(点第2个方格)因为他会添加一个字符串,影响到你物品上的属性,所以最好是先把物品的基础做好后再加入其他属性。
最后是如何改成无法破坏的,方法有两个:1改耐久。2添加一个无法破坏属性。
改耐久的方法:找到MAX Dur这个字段改成0就可以无法破坏了,注意也要清理一下属性!
补充:装备如何去掉防御!
在Max Dur那个字段前边有个Defense(防御)的字段,改成0装备的的防御就是-10了!游戏里没有显示。防御是越低越好。武器和首饰没有这个属性字段!所以不比找了,找不到的
UdieToo中文属性对照表
Strength 增加力量
Energy 增加精力
Dexterity 增加敏捷
Vitality 增加体力
Stat Points 没用
Skill Points 没用
Life 没用
Max Life 增加最大生命
Mana 没用
Max Mana 增加最大魔法
stamina 没用
Max Stamina 没用
level 没用
experience 没用
gold 没用
goldbank 没用
Enhanced Defense % 防御增加百分比
Enchanced Damage % 伤害增加百分比
Enchanced Min Dmg % 增加最小伤害百分比
Attack Rating 增加命中率
Chance of Blocking % 增加格挡率
Min 1-handed Dmg 增加单手最小伤害
Max 1-handed Dmg 增加单手最大伤害
Min 2-handed Dmg 增加双手最小伤害
Max 2-handed Dmg 增加双手最大伤害
Damage % nv 伤害增加百分比Regenerate Mana % nv 法力再生
Regenerate Mana Plus % 法力再生(隐藏)
Heal Stemina Plus % 耐力恢复
lastexp 没用
nextexp 没用
Defense 增加防御
Def vs Missile 增加对近战的防御
Def vs Melee 增加对远程攻击的防御
Damage Reduced By 伤害减少
Magic Dmg Reduced By 魔法伤害减少
Damage Reduced By % 伤害减少百分比
Magic Resistance % 魔法抵抗百分比
Max Magic Resistance % 百分比增加最大魔法抵抗的百分比
Fire Resistance % 增加火抗的百分比
Max Fire Resistance % 增加最大火抗的百分比
Lightning Resistance % 增加电抗的百分比
Max Lightning Resistance % 增加最大电抗的百分比
Cold Resistance % 增加冰抗的百分比
Max Cold Resistance % 增加最大冰抗的百分比
Poison Resistance % 增加毒抗的百分比
Max Poison Resistance % 增加最大毒抗的百分比
damageaura 没用
Fire Damage 增加火焰伤害
Max Fire Damage 增加火焰伤害最大值
Lightning Damage 增加闪电伤害
Max Lightning Dmg 增加闪电伤害最大值
Magic Damage 增加魔法伤害
Max Magic Damage 增加魔法伤害最大值
Cold Damage 增加寒冷伤害
Max Cold Damage 增加寒冷伤害最大值
Cold Length 冻结目标的时间
Poison Damage 增加毒伤害
Max Poison Dmg 增加毒伤害最大值
Poison Length 目标中毒的持续时间
Life Stolen Per Hit Min 没用
Life Stolen Per Hit Max 偷取生命
Mana Stolen Per Hit Min 没用
Mana Stolen Per Hit Max 偷取法力
Stamina Drain Min 没用
Stamina Drain Max 没用
Stun Length 使目标眩晕的时间
Run/Walk Speed % nv 跑步速率增加百分比(隐藏)
Attack Speed % nv 攻击速率增加百分比(隐藏)
other_animrate 没用
quantity 没用
value 没用
Durabilty 没用
Max Durability 增加装备耐久
Replenish Life 自行恢复生命值
Max Durability % 没用
Life % 增加生命上限%
Mana % 增加法力上限%
Attacker Takes Damage Of 反伤
Extra Gold From Monsters % 怪掉的钱增加
Chance Of Getting Magic Items % 这个就是**
Knock Back 击退
Time Duration (未测试)
Add Class Skill 加单人技能
Unsentparam1 未知属性1
Add experience 增加百分比得到的经验值
Heal after kill 加X生命在杀死一只怪物后
Reduced prices 降低商人价格%
Double Herb Duration (未测试)
Light Radius 增加光照范围
Light Color nv 光照范围(隐藏)
Requirements % 物品对基本属性的需求
Level Require 没用
Increased Attack Speed 提升攻击速度%
Level Require % 增加等级需求
Last block frame 格挡有关
Faster Run/Walk 提升跑步速度%Non Class skill 无职业限制技能
state 特殊状态,比如头上永远顶个经验祭坛
Faster Hit Recovery Rate 加快打击恢复
Monster player count 没用
Poison override 没用
Faster Block Rate 快速格挡速度
Bypass undead 没用
Bypass demons 没用
Faster Cast Rate 快速释法速度
Bypass beasts 没用
Single Skill 增加职业限制技能
Rest in peace 杀死怪物后恢复平静
Curse resistance 抗诅咒几率
Poison Length Reduced By % 自己的中毒时间减少
Damage 增加伤害
Hit Causes Monster To Flee % 使怪物怪物会逃跑
Hit Blinds Target 打中的敌人会失明
Damage To Mana % 受损生命转化为提高法力
Ignore Target Defense 无视目标防御
Target Defense % 减少目标防御%
Prevent Monster Heal 防止怪物回血
Half Freeze Duration 自己的冰冻时间减半
Bonus To Attack Rating % 增加百分比额外的命中率
Reduce Monster Defense per Hit 每次打中都减少怪物的防御
Damage To Demons % 增加对恶魔系怪物的伤害
Damage To Undead % 增加对不死系怪物的伤害
Attack Rating Against Demons 增加对恶魔系怪物的命中率
Attack Rating Against Undead 增加最不死系怪物的命中率
Throwable (未测试)
Elemental Skill 增加火焰技能
All Skill Levels 增加所有技能
Attacker Takes Lightning Dmg Of 攻击者受到电伤害
ironmaiden_level 没用
lifetap_level 没用
thorns_percent 没用
bonearmor 没用
bonearmormax 没用
Attack Freezes Target 冻结目标
Chance of Open Wounds 撕开伤口的几率
Chance of Crushing Blow 压碎攻击的几率
Kick Damage 增加脚踢伤害
Mana After Each Kill 加法力在杀死一只怪物后
Life After Each Demon Kill 加生命在杀死恶魔系怪物后
Extra Blood 没用
Chance of Deadly Strike 致命攻击的几率Fire Absorbs % 火焰吸收%
Fire Absorbs 火焰吸收
Lightning Absorbs % 闪电吸收%
Lightning Absorbs 闪电吸收
Magic Absorbs % 魔法吸收%
Magic Absorbs 魔法吸收
Cold Absorbs % 冰冷吸收%
Cold Absorbs 冰冷吸收
Slows Target By % 使目标减缓%
Aura 灵气赐予
Indestructible 装备无法破坏
Cannot be Frozen 不会被冻结
Slower Stamina Drain % 没什么用
ReAnimate 杀死怪物后复活为
Pierce Attack % 穿透攻击
Fire Magic Arrows or Bolts 射出魔法箭
Fire Explosive Arrows or Bolts 射出爆炸箭
Min Throw Dmg nv 增加百分比最小远程攻击
Max Throw Dmg nv 增加百分比最大远程攻击
UnCoded 未知属性
UnCoded
UnCoded
UnCoded
UnCoded
UnCoded
UnCoded
UnCoded
UnCoded
UnCoded
UnCoded
UnCoded
UnCoded
UnCoded
UnCoded
UnCoded
UnCoded
UnCoded
Attack Vs Monster 对特定怪物增加命中率
Damage Vs Monster 对特定怪物增加伤害
fade 身体透明化
Armor override % 没用
Unused183 …
Unused184 …
Unused185 …
Unused186 …
Unused187 …
Add Skill Tab 加入单系技能
Unused189 没用
Unused190 …
Unused191 …
Unused192 …
Unused193 …
Increased Sockets 增加凹槽(需先激活)
Skill On Attack 攻击时释放特定魔法
Skill On Kill 杀死怪物时释放特定魔法
Skill On Death 自己死亡时放特定魔法
Skill On Hit 打中时释放特定魔法
Skill On Levelup 升级时释放特定魔法
Unused200 没用
Skill On Get Hit 被打中时释放特定魔法
Unused202 没用
Unused203 …
Charged Skill 特定聚气技能
Unused205 没用…
Unused206 …
Unused207 …
Unused208 …
Unused209 …
Unused210 ..
Unused211 …
Unused212 ..
Unused213 …
Defense (on Lvl) 按等级增加防御
Enhanced Defense (on Lvl) 按等级提高防御
Life (on Lvl) 按等级提高生命值
Mana (on Lvl) 按等级提高魔法值
Maximum Damage (on Lvl) 按等级提高最大伤害
Enhanced MaxDmg (on Lvl) 按等级提高最大伤害%
Strength (on Lvl) 按等级增加力量
Dexterity (on Lvl) 按等级增加敏捷
Energy (on Lvl) 按等级增加精力
Vitality (on Lvl) 按等级增加体力
Att Rating (on Lvl) 按等级增加命中率
Bonus to Att Rating % (on Lvl) 按等级提高额外的命中率
Maximum Cold Dmg (on Lvl) 按等级增加最大寒冷伤害
Maximum Fire Dmg (on Lvl) 按等级增加最大火伤害
Maximum Lightning Dmg (on Lvl) 按等级增加最大闪电伤害
Maximum Poison Dmg (on Lvl) 按等级增加最大毒伤害
Cold Resistance % (on Lvl) 按等级增加百分比冰抗
Fire Resistance % (on Lvl) 按等级增加百分比火抗
Lightning Resistance % (on Lvl) 按等级增加百分比电抗
Poison Resistance % (on Lvl) 按等级增加百分比毒抗
Absorbs Cold Damage (on Lvl) 按等级提高吸收寒冷伤害能力
Absorbs Fire Damage (on Lvl) ……吸收火伤害能力
Absorbs Lightning Damage (on Lvl) ……吸收闪电伤害能力
Absorbs Poison (per lvl) "很诱惑的属性,不过没用"
Attacker Takes Damage of (on Lvl) 按等级反伤
Extra Gold From Monsters % (on Lvl) 按等级提高怪掉的钱
Chance of Getting Magic Items % (on Lvl) 按等级提高**几率
Heal Stamina Plus % (on Lvl) 没用
Maximum Stamina (on Lvl) 没用
Damage to Demons % (on Lvl) 没用
Damage to Undead % (on Lvl) 没用
Att Rating against Demons (on Lvl) 没用
Att Rating against Undead (on Lvl) 没用
Chance of Crushing Blow (on Lvl) 按等级提高压碎攻击的几率
Chance of Open Wounds (on Lvl) ……提高撕开伤口的几率
Kick Damage (on Lvl) 按等级提高踢伤害
Chance of Deadly Strike (on Lvl) 按等级提高致命攻击几率
Find Gems per level 没用
Repair 1 Durability In Seconds 按时间恢复耐久
Replenish 1 Quantity In Seconds 回复数量
Increased Stack Size 增加数量
UnCoded 没用
UnCoded …
UnCoded …
UnCoded …
UnCoded …
UnCoded …
UnCoded ..
UnCoded …
UnCoded .
UnCoded ..
UnCoded .
UnCoded .
UnCoded .
Defense (by Time) [1] 以下为属性/时间
Defense (by Time) [2]
Life (by Time)
Mana (by Time)
Max Damage (by Time) [1]
Max Damage (by Time) [2]
Strength (by Time)
Dexterity (by Time)
Energy (by Time)
Vitality (by Time)
Attack Rating (by Time) [1]
Attack Rating (by Time) [2]
Max Cold Dmg (by Time)
Max Fire Dmg (by Time)
Max Lightning Dmg (by Time)
Max Poison Dmg (by Time)
Cold Resistance % (by Time)
Fire Resistance % (by Time)
Lightning Resistance % (by Time)
Poison Resistance % (by Time)
Absorbs Cold Damage (by Time)
Absorbs Fire Damage (by Time)
Absorbs Lightning Damage (by Time)
Blessed Aim
Gold From Monsters % (by Time)
Find Magic Items % (by Time)
Heal Stamina Plus % (by Time)
Max Stamina (by Time)
Damage vs Demon % (by Time)
Damage vs Undead % (by Time)
Attack Rating vs Demon (by Time)
Attack Rating vs Undead (by Time)
Chance of Crushing Blow (by Time)
Chance of Open Wounds (by Time)
Kick Damage (by Time)
Chance of Deadly Strike (by Time)
item_find_gems_bytime 没用
item_pierce_cold 减少敌人对冰技能抵抗%
item_pierce_fire 减少敌人对火技能抵抗%
item_pierce_ltng ……对闪电技能抵抗%
item_pierce_pois ……对毒素技能的抵抗%
item_damage_vs_monster 没用
item_damage_percent_vs_monster …
item_tohit_vs_monster …
item_tohit_percent_vs_monster …
item_ac_vs_monster …
item_ac_percent_vs_monster …
firelength …
burningmin …
burningmax …
progressive_damage …
progressive_steal ..
progressive_other ..
progressive_fire …
progressive_cold …
progressive_lightning …
item_extra_charges …
progressive_tohit …
poison_count …
damage_framerate …
pierce_idx …
passive_fire_mastery 增加百分比火技能伤害
passive_ltng_mastery ……闪电技能伤害
passive_cold_mastery ……寒冷技能伤害
passive_pois_mastery 百分比转为毒素伤害
passive_fire_pierce 减敌人对火技能抗性(测试效果为增加元素伤害上限)
passive_ltng_pierce ……对闪电技能抗性
passive_cold_pierce ……对寒冷技能抗性
passive_pois_pierce ……对毒素技能抗性
passive_critical_strike 不清楚
passive_dodge 三闪之一
passive_avoid 三闪……
passive_evade 三闪……
passive_warmth 热情
passive_mastery_melee_th 未测试
passive_mastery_melee_dmg …
passive_mastery_melee_crit …
passive_mastery_throw_th …
passive_mastery_throw_dmg …
passive_mastery_throw_crit …
passive_weaponblock …
passive_summon_resist …
modifierlist_skill 没用
modifierlist_level 没用
last_sent_hp_pct 没用
source_unit_type 没用
source_unit_id 没用
shortparami 未测试
questitemdifficulty 未测试
passive_mag_mastery 未测试
passive_mag_pierce 未测试
自己看吧
java基础都有那些?
java语法基础
1,关键字:其实就是某种语言赋予了特殊含义的单词。
保留字:其实就是还没有赋予特殊含义,但是准备日后要使用过的单词。
2,标示符:其实就是在程序中自定义的名词。比如类名,变量名,函数名。包含 0-9、a-z、$、_ ;
注意:
1),数字不可以开头。
2),不可以使用关键字。
3,常量:是在程序中的不会变化的数据。
4,变量:其实就是内存中的一个存储空间,用于存储常量数据。
作用:方便于运算。因为有些数据不确定。所以确定该数据的名词和存储空间。
特点:变量空间可以重复使用。
什么时候定义变量?只要是数据不确定的时候,就定义变量。
变量空间的开辟需要什么要素呢?
1,这个空间要存储什么数据?数据类型。
2,这个空间叫什么名字啊?变量名称。
3,这个空间的第一次的数据是什么? 变量的初始化值。
变量的作用域和生存期:
变量的作用域:
作用域从变量定义的位置开始,到该变量所在的那对大括号结束;
生命周期:
变量从定义的位置开始就在内存中活了;
变量到达它所在的作用域的时候就在内存中消失了;
数据类型:
1):基本数据类型:byte、short、int、long、float、double、char、boolean
2):引用数据类型: 数组、类、接口。
级别从低到高为:byte,char,short(这三个平级)-->int-->float-->long-->double
自动类型转换:从低级别到高级别,系统自动转的;
强制类型转换:什么情况下使用?把一个高级别的数赋给一个别该数的级别低的变量;
运算符号:
1)、算术运算符。
+ - * / % %:任何整数模2不是0就是1,所以只要改变被模数就可以实现开关运算。
+:连接符。
++,--
2)、赋值运算符。
= += -= *= /= %=
3)、比较运算符。
特点:该运算符的特点是:运算完的结果,要么是true,要么是false。
4)、逻辑运算符。
& | ^ ! && ||
逻辑运算符除了! 外都是用于连接两个boolean类型表达式。
&: 只有两边都为true结果是true。否则就是false。
|:只要两边都为false结果是false,否则就是true
^:异或:和或有点不一样。
两边结果一样,就为false。
两边结果不一样,就为true.
& 和 &&区别: & :无论左边结果是什么,右边都参与运算。
&&:短路与,如果左边为false,那么右边不参数与运算。
| 和|| 区别:|:两边都运算。
||:短路或,如果左边为true,那么右边不参与运算。
5)、位运算符:用于操作二进制位的运算符。
& | ^
<< >> >>>(无符号右移)
练习:对两个变量的数据进行互换。不需要第三方变量。
int a = 3,b = 5;-->b = 3,a = 5;
a = a + b; a =8;
b = a - b; b =3;c
a = a - b; a =5;
a = a ^ b;//
b = a ^ b;//b= a ^ b ^ b = a
a = a ^ b;//a= a ^ b ^ a = b;
练习:高效的算出 2*8 ------------------> 位移运算的考验,java基础面试中它的曝光率不低哦
5,语句。
If switch do while while for
这些语句什么时候用?
1)、当判断固定个数的值的时候,可以使用if,也可以使用switch。
但是建议使用switch,效率相对较高。
switch(变量){
case 值:要执行的语句;break;
…
default:要执行的语句;
}
工作原理:用小括号中的变量的值依次和case后面的值进行对比,和哪个case后面的值相同了
就执行哪个case后面的语句,如果没有相同的则执行default后面的语句;
细节:1):break是可以省略的,如果省略了就一直执行到遇到break为止;
2):switch 后面的小括号中的变量应该是byte,char,short,int四种类型中的一种;
3):default可以写在switch结构中的任意位置;如果将default语句放在了第一行,则不管expression与case中的value是否匹配,程序会从default开始执行直到第一个break出现。
2)、当判断数据范围,获取判断运算结果boolean类型时,需要使用if。
3)、当某些语句需要执行很多次时,就用循环结构。
while和for可以进行互换。
区别在于:如果需要定义变量控制循环次数。建议使用for。因为for循环完毕,变量在内存中释放。
break:作用于switch ,和循环语句,用于跳出,或者称为结束。
break语句单独存在时,下面不要定义其他语句,因为执行不到,编译会失败。当循环嵌套时,break只跳出当前所在循环。要跳出嵌套中的外部循环,只要给循环起名字即可,这个名字称之为标号。
代码片段:
z: //for循环标号
for(int x=0;x<3;x++){
for(int y=0;y<2;y++){
//不带标号的就是结束整个循环体的作用,在那个循环内部就结束哪个循环
if(x==1)break;
//带标号跳过break后面的语句,回到标号位置的循环,继续该循环下次的条件判断,
//已决定是否执行该循环体
if(x==2&&y==1)break z;
}
}
continue:只作用于循环结构,继续循环用的。
作用:结束本次循环,继续下次循环。该语句单独存在时,下面不可以定义语句,执行不到。
6,函 数:为了提高代码的复用性,可以将其定义成一个单独的功能,该功能的体现就是java中的函数。函数就是体现之一。
java中的函数的定义格式:
修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数1,…){
执行语句;
return 返回值;
}
当函数没有具体的返回值时,返回的返回值类型用void关键字表示。
如果函数的返回值类型是void时,return语句可以省略不写的,系统会帮你自动加上。
return的作用:结束函数。结束功能。
如何定义一个函数?
函数其实就是一个功能,定义函数就是实现功能,通过两个明确来完成:
1)、明确该功能的运算完的结果,其实是在明确这个函数的返回值类型。
2)、在实现该功能的过程中是否有未知内容参与了运算,其实就是在明确这个函数的参数列表(参数类型&参数个数)。
函数的作用:
1)、用于定义功能。
2)、用于封装代码提高代码的复用性。
注意:函数中只能调用函数,不能定义函数。
主函数:
1)、保证该类的独立运行。
2)、因为它是程序的入口。
3)、因为它在被jvm调用。
函数定义名称是为什么呢?
答:1)、为了对该功能进行标示,方便于调用。
2)、为了通过名称就可以明确函数的功能,为了增加代码的阅读性。
重载的定义是:在一个类中,如果出现了两个或者两个以上的同名函数,只要它们的参数的个数,或者参数的类型不同,即可称之为该函数重载了。
如何区分重载:当函数同名时,只看参数列表。和返回值类型没关系。
7,数 组:用于存储同一类型数据的一个容器。好处:可以对该容器中的数据进行编号,从0开始。数组用于封装数据,就是一个具体的实体。
如何在java中表现一个数组呢?两种表现形式。
1)、元素类型[] 变量名 = new 元素类型[元素的个数];
2)、元素类型[] 变量名 = {元素1,元素2...};
元素类型[] 变量名 = new 元素类型[]{元素1,元素2...};
---------------------------------------------------------
//二分查找法。必须有前提:数组中的元素要有序。
public static inthalfSeach_2(int[] arr,int key){
int min,max,mid;//定义最小,最大,中间数
min = 0;//最小为0
max =arr.length-1;// 最大为数组的长度-1
mid =(max+min)>>1; //(max+min)/2;//中间数为最大加最小除以2
while(arr[mid]!=key){//如果数组中间值不等于key
if(key>arr[mid]){//如果key>中间值
min = mid+ 1;
}
elseif(key
max = mid- 1;
if(max
return -1;
mid =(max+min)>>1;
}
return mid;
}
知识拓展:
java内存。
1:寄存器。2:本地方法区。3:方法区。4:栈。5:堆。
栈:存储的都是局部变量 ( 函数中定义的变量,函数上的参数,语句中的变量 );
只要数据运算完成所在的区域结束,该数据就会被释放。
堆:用于存储数组和对象,也就是实体。啥是实体呢?就是用于封装多个数据的。
1:每一个实体都有内存首地址值。
2:堆内存中的变量都有默认初始化值。因为数据类型不同,值也不一样。
3:垃圾回收机制。
学习JAVA应该从哪一部开始很多人都很迷茫,下面是我整理的学习路线和方向一共四点。希望对你有帮助!
①【学习语言基础】
很显然,掌握语言基础是第一步。如果你不了解基础知识,那么你就不知道自己是否做错了或者接下来该怎么做。当然,这并不是要求你把所有的基础知识都记住,比如所有的 Java关键字、核心概念或者基本编码技术等。
②【开始编写一些小程序】
如果你确信自己对大多数的基础知识和概念足够熟悉,并且能够以某种方式将它们联系起来,那么你就可以进行下一步了,你可以开始尝试编写一些非常基本的 Java 程序,比如打印 hello world、实现简单的加减法,等等。
③【 使用 Java API 编写高级程序】
当你完成了大部分的基础程序编写,并且掌握了基本的编程技巧之后,就可以进行下一步了。我会建议你努力学习 Java 集合和 Java IO 内部的 API。你需要熟悉这些 API 提供的各种类和接口,并利用它们来创建程序。需要注意的是,你应该查找已经存在的 API 和方法来实现功能,而不是自己实现这些逻辑。你的任务是熟悉这些 API,因此你只能够在这些已有的 API 中寻求解决方案。
④【编写桌面程序和 Web 应用】
通过这一步的学习,面对任何 Java 面试你都能够信心满满,当你讨论 Java 相关的话题时也能够充满自信。你需要至少编写一个 Java 桌面或者 GUI 应用程序,比如计算器,然后再编写一个 Web 应用程序,比如医院管理程序。在前面的学习中,你已经掌握了最基本的 Java 知识,现在你需要去探索,然后编写出这两个应用程序。
重要的是,它可以帮助你养成不惜一切代价完成一项任务的好习惯。这种持之以恒的态度对你职业生涯的长远发展是非常重要的。
java基础说的也就是他的语法,学完语法就可以在语法基础上延伸各种各样的东西。
1、java初学者,首先推荐看《java从入门到精通》很基础的2、基础掌握之后去练习,做小项目swing之类的3、开始学java web知识,将jdbc+servlet做个中级左右的项目出来。如果想看视频学习的话可以考虑到siki学院去看下相关的视频
一、标识符
java对各种变量、方法和类等要素命名时使用的字符序列成为标识符;通俗点,凡是自己可以起名字的地方都叫标识符,都遵守标识符的规则
1.标识符命名规则:
1)标识符由字符、下划线、美元符或数字组成。
2)标识符应以字符、下划线、美元符开头
3)java标识符大小写敏感,长度无限制
4)约定俗成,java标识符选取应该注意“见名知意”且不能与java语言的关键字(eclipes中带颜色的基本都是关键字)重名
二、关键字
java中一些赋以特定含义,用作专门用途的关键的字符串成为关键字(keyword);且大多数编辑器都会将关键字用特殊方式标出 所有java关键字都是小写英文
一些常用关键字:
三、java的基本数据类型
1.java常量
java的常量值用字符串表示,区分为不同的数据类型。如:整型常量:1234实型常量:3.14字符常量:’a’逻辑常量:true、false字符串常量:”HelloWorld”
注意:
1)区分字符常量和字符串常量
字符常量是单引号引起来的单个,字符串常量是双引号引起来的不限长度
由于java采用Unicode编码,每个字符占两个字节,因而可用天十六进制编码形式表示,当然也可以用一个中文表示(单个中文占用两个字节)
2)”常量”这个名次还会用在另外其他语境中表示值不可变的变量
2.java变量
java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。java程序中每一个变量都属于特定的数据类型,在使用前必需对其进行声明,声明格式为:type varName [=value]例如:int i =100;foloat f=12.3f;double d1,d2,d3=0.123;(声明了三个变量,其中d1,d2是默认值,d3=0.123)String s=”hello”
从本质上讲,变量其实是内存中的一小块区域,使用变量名来访问这块区域,因此,每一个变量使用前必需先声明,然后必需进行赋值,才能使用。
1)java变量分类
按被声明的位置划分:
局部变量:方法或语句块内部定义的变量,只能在被定义的方法或语句块内使用
成员变量:方法外部、类的内部定义的变量,可以在整个类中使用,包括类里的方法或语句块内也可以使用
注意:类外面是不能有变量的声明的
按所属的数据类型划分:
基本数据类型变量
引用数据类型变量
四、运算符
java语言支持如下运算符:
算术运算符:+ - * / % ++ --
关系运算符:> < >= <= == !=
逻辑运算符:! & | ^ && ||
位运算符:& | ^ ~ >> << >>>
赋值运算符:=
拓展赋值运算符:+ = -= *= /=
字符串链接运算符:+
三目条件运算符 ? :
1.算数运算符
注意:
1)
位运算符中的!、&、|、^跟罗技运算符相同,只是位运算符是对变量的二进制进行操作,我个人是用不到的,所以不在这里多做介绍
2)
++(—)
在前时先运算再取值
在后时先取值再运算
2.逻辑运算符
例如:
3.扩展赋值运算符
4.字符串连接符
“ + ”运算符两侧的操作数中只要有一个是字符串类型,系统会自动将另一个操作数转换为字符串然后进行连接,例如:
4 + 5 = 94 + “ab” = “4ab”
5.三目条件运算符
语法格式: x ? y : z 其中x为boolean类型表达式,先计算x的值,若为true,则整个三目运算的结果为表达式y的值,否则整个运算结果为表达式z的值。
五、表达式和语句
1.表达式
表达式是符合一定语法规则的运算符和操作数的序列,例如:a5.0 + a(a – b) * c – 4i < 30 && i %10 !=0
1)表达式的类型和值
表达式中的操作数进行运算得到的结果称为表达式的值
表达式值的数据类型即为表达式的类型
2)表达式的运算顺序
应按照运算符的优先级从高到低的顺序进行
优先级相同的运算符按照实现约定的结合方式进行
我个人觉得运算顺序这块是可以忽略的,首先我的逻辑思维能力不是特别强,另外我的记性也不是特别好,所以如果我需要在表达式中区分优先级的话我会选择加括号。但是我觉得对于一些比较复杂且关键的逻辑运算,如果个人逻辑运算能力加记忆都比较好可以保证不出错的话,善用罗技运算符优先级未尝不是一种不让别人看懂你代码copy的手段。算是一种小小的防护吧,反正我这种人是不会去尝试分析这种代码的,太累
2.分支(条件)语句
ifif … elseif … else if … else ifif … else if … else if …elseswitch () {case xx:……………case xx:……………default:……………}
1.java中switch语句只能探测int类型的值(char类型的值也可以,因为他可以转换城int类型)
2.小心case穿透,所以最好与break连用
3.多个case可以连用,如下的示例代码也可以这样写(当i=1,2,18都会输出18):
3.循环语句
for(…;…;…){……}while(…){……}先判断再执行大括号里面的内容,然后再判断是否要继续执行do{……} whille(…); 先执行大括号里面的内容再判断是否要继续执行
4.break & continue语句
break语句用于终止某个语句块的执行。用在循环体语句中么可以强行退出循环continue语句用在循环体语句中,用于终止某次循环过程,跳过循环中continue语句下面未执行的循环,开始下一次循环过程
八、方法
java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段,声明格式:[修饰符1 修饰符2 …] 返回值类型 方法名 (形式参数列表) {java语句}
形式参数:在方法被调用时用于接受外界输入的数据
实参:调用方法时实际纯给方法的数据
返回值:方法在执行完毕后返回给调用他的环境的数据
返回值类型:实现约定的返回值的数据类型,如无返回值,必需给出返回值类型void
java语言中调用方法:对象名.方法名(实参列表)
实参的数目、数据类型和次序必需和所调用方法声明的形参列表匹配
return语句终止方法的运行并指定要返回的数据
java中进行函数调用传递参数时,遵循值传递的原则:
基本类型传递的是该数据值本身,引用累心美国传递的是对对象的引用,而不是对象本身
例子中的方法1,前面定义的数据类型为void, 所以方法中不能有return返回值,方法4中因为有return返回值,所以前面必需定义为返回值的类型,也就是m4前面那个int
九、递归调用
递归调用是指在方法执行过程中出现该方法本身的调用
先看一个例子,这是一个简单的递归调用:
简单分析下:
1.首先main主方法中输出字符串,内容是test方法当参数等于5的时候的返回值2.然后将参数5传入test方法,返回值是:5 * test(4)3.再次将参数4传入test方法中,返回值是:4 * test(3)4.再将参数3传入test方法中,返回值是:3 * test(2)5.再讲参数2传入test方法中:返回值是:2 * test(1)6.再将参数1传入到方法中:返回值是:1然后程序开始往回走,返回值传入test(1)中得到2*1再往回走,将刚刚得到的2*1传入到test(2)中得到3*2*1还要往回走,将刚刚得到的3*2*1传入到test(3)中得到4*3*2*1还要往回走,将刚刚得到的4*3*2*1传入到test(4)中也就是test(5)的返回值,得到5*4*3*2*1最后将test5的返回值传入到我们的主方法输出于语句中5*4*3*2*1=120,那么我们的输出语句输出的应该为120
这就是简单的递归调用的例子了
再来看一个例子:
非递归的写法:
请自行领悟
最后奉上java基础语法完整学习路线图,除此之外还有精心整理的其他java学习路线图,学习书籍电子书,阿里巴巴手册,视频教程等即可点此领取:
https://zhuanlan.zhihu.com/p/6
在.NET上运行Java IKVM.NET入门
一 介绍
IKVM NET是一个针对Mono和微软 net框架的java实现 其设计目的是在 NET平台上运行java程序 它包含了以下的组建 * 一个用 NET实现的java虚拟机* 一个java类库的 NET实现* 致力于在java和 NET之间交互的工具
二 IKVM NET的组件
IKVM NET包含以下的部分 * IKVM Runtime dll VM运行时和所有支持代码 它包括以下的功能 Byte Code JIT 编译器和验证器 使用JIT将Java Byte Code编译为CIL(C中间语言)
对象模式映射结构 将 NET中的System Object System String System Exception映射为java代码中的java lang Object java lang String java lang Throwable 管理本地方法(在Classpath中)的 NET重新实现
* IKVM GNU Classpath dll 被编译的GNU Classpath版本 它是由自由软件基金会实现的java类库和一些IKVM NET附加代码组成的 注意 这里的GNU Classpath不是IKVM NET的一部分 但是前者被用在IK VM NET中
* IKVM JNI [Mono|CLR Win ] dll 通过实现JNI接口管理C++汇编 作为一个可选部分 只在程序使用自己的本地库时才被用到 而对于纯java程序来讲是不会被用到的
* ikvm exe 与java exe很类似的启动执行程序(动态模式)
* ikvmc exe 静态编译器 被用来编译java类和jar使其成为 NET汇编(静态模式)
* ikvmstub exe 一个从 NET汇编生成存根类的工具 就如javap一样反编译 NET汇编 IKVM NET了解如何存根并用实际的 NET类型引用替换对存根的引用
* IKVM AWT WinForms dll 非常有限的零散AWT实现
二 项目状态
此项目目前正在开发 将最大化实现与JDK 的兼容 但是仍存在一些漏洞(尤其在Classpth API中)
* AWT和Swing还未有功能
* 安全性是IKVM平台的一个大遗漏 此问题将依靠 NET平台提供的旧有的 但功能强大的安全模式而被解决 虽然这样 目前项目已具备能成功运行大型java项目的能力
三 IKVM原理
如何替换JVM IKVM应用包含了采用 NET实现的java虚拟机 在一些场合 我们可以用它替换掉java 例如 java jar myapp jar 将被替换为 ikvm jar myapp jar
在 NET应用中使用java类库IKVM NET包含ikvmc 这个在java bytecode与 NET中间语言的转换器 如果我们使用一个被用在 NET平台的java库的话 运行ikvmc –target library mylib jar(mylib jar在这里指代我们的jar文件)来生成mylib dll 例如apache FOP项目是一个开源的XSL FO处理器项目 它使用java语言编写的用于从xml生成PDF文档 使用IKVM NET技术 我们可以将apache FOP用在任何的 NET应用中 这样在开发 NET应用的同时利用IKVM便可以使用java开源项目这个免费的软件仓库 尽管在IKVM NET没有提供在 NET中使用的java编译器 但是我们可用开源的Jikes编译器将java源代码编译为JVM bytecode 然后使用ikvmc –target exe myapp jar来生产 NET执行文件 我们甚至可以通过包含ikvmstub应用的方式在我们的java代码中用 NET API
四 IKVM使用入门
系统准备Windows平台 Microsoft NET Framework SDK Windows或者Linux平台 Mono Framework
开始安装在Windows和Linux平台上安装过程是相同的 在下载二进制发布版后 将文件解压缩 打开命令或者shell窗口 cd进入ikvm\bin目录 执行ikvm 如果我们操作正确的话 我们将看到以下的输出
usage ikvm [ options]
[args……] (to execute a class) or ikvm jar [ options]
[args……] (to execute a jar file) ……
为了方便使用 我们可将ikvm\bin目录加入到系统path 现在我们将使用IKVM就像使用JVM一样 并不需要配置 如果我们需要在 NET或者Mono环境下使用IKVM 请仔细阅读下面的文字说明 * 首先下载Jikes编译器 如果我们计划开发在java中开发代码 运行于 NET环境的话 我们将要一个java编译器 IKVM NET没有提供这个编译器 所以我们需要能生成标准java类文件的编译器 Jlikes是一个好选择 它是一个优秀的开源项目 并应用在多种平台 当然Sun提供的jdk也很好
* 在Windows的全局汇编缓冲区中安装IKVM dll 在Windows中运行基于IKVM dll的 NET应用程序时 NET框架必须定位这些dll的位置 系统首先在全局汇编缓冲区中查找 然后再当前目录中查找 如果我们想不在当前目录中安装这些dll文件的话 我们就要将它们安装在全局汇编缓冲区中 在Windows控制面板中访问 NET框架配置 增加一个汇编缓冲区 我们至少要安装IKVM GNU Classpath dll和IKVM Runtime dll
设置环境在我们开始编写代码之前需要准备一下我们的环境 添加以下路径到系统PATH环境变量中 * 包含IKVM执行文件的目录
* 包含C#编译器(在Windows/Mono中为csc)的目录 通常在Windows中为C \WINDOWS\Microsoft NET\Framework\v * 包含java编译器(javac或者jikes)的目录
动态执行java应用程序IKVM NET包括了一个C#实现的java虚拟机 我们可以从一个例子开始——进入IKVMROOT\samples\hello目录 编译示例程序
Javac Hello jar cfm hello jar manifest mf Hello class
现在 在使用javac编译了Hello类后 我们使用IKVM运行此类
ikvm Hello
这个命令将启动IKVM IKVM查找名为Hello class的文件 如果找到 则将其装载并动态执行bytecode 此时Hello程序将要求我们输入名字 之后我们将看到一个问候信息
如果在上面的过程中发生问题 请检查下面的地方 * 检查命令行 ikvm像java一样需要我们输入正确的类名
* 如果ikvm报告ClassNotFoundException 请检查CLASSPATH环境变量是否被设置 如果被设置 请清除CLASSPATH或者将当前目录加入到CLASSPATH中以使ikvm能够在当前目录中找到类
如果运行jar文件 我们可键入
ikvm jar hello jar
提示 详细的命令行选项可以参考ikvm手册
将java程序转换为 NET程序IKVM NET包含ikvmc这个能够将jar文件转换为 NET的dll库文件和exe应用的工具 下面我们将学习如何将java应用转换为一个 NET执行文件 进入IKVMROOT\samples\hello目录输入以下命令
ikvmc hello jar
注意 当我们使用Mono时 我们需要告诉ikvmc如何找到GNU Classpath dll 例如
ikvmc reference /usr/lib/IKVM GNU Classpath dll hello jar
在命令执行完后 我们将发现hello exe已被生成在当前目录 * 在Windows/ NET环境下 如果我们得到了FileNotFound的异常 请记住检查 NET框架希望在当前目录或是全局汇编缓冲区中寻找dll文件 我们可以通过上面讲的方法将dll安装到全局汇编缓冲区中 或者将dll文件直接复制到当前目录
* 在Linux/Mono环境下 我们使用下面的命令执行hello exe
mono hello exe
在java中开发 NET应用首先进入IKVMROOT\samples\usenetapi目录 找到ShowDir java文件 这个java应用使用了 NET API来显示当前目录下的文件列表 打开这个文件 我们会发现其导入的包名以cli开头 这些并不是java API包 它们是映射到 NET命名空间的 伪 包 需要查看更多信息请看IKVM的开发者手册
第一步 生成java存根文件IKVM没有提供java编译器 所以我们可以使用标准的java编译器 由于java编译器只能编译使用了java API的应用程序 而不是使用 NET API的应用 所以我们在这里需要 愚弄 一下java编译器使其相信名为cli System IO的包是一个真正的java包 帮助我们完成这项工作的是ikvmstub程序 它从 NET dll生成jar文件 这个被生成的jar文件包含了与 NET类对应的java类和接口 但是并不包含真正的代码 只包含一些映射信息 这样做便会通过java编译器的检查和编译
ikvmstub mscorlib dll
注意 在Linux Mono环境下 我们必须输入dll文件的完整路径 例如
ikvmstub /usr/lib/mscorlib dll
在编译完成后 我们将在当前目录下发现一个名为mscorlib jar的文件
第二步 编译java源代码现在我们将编译java源代码 如果使用javac的话 可输入以下命令 javac classpath mscorlib jar ShowDir java
在命令完成后 ShowDir class文件将出现当前目录下
第三步 生成 NET执行文件最后我们将转换java class文件为 NET应用程序 正如前面讲的 ikvmc ShowDir class
注意 在Linux Mono环境下 我们需要使用前面提到的 reference选项
ikvmc reference /usr/lib/IKVM GNU Classpath dll ShowDir class
这时我们便可以看到ShowDir exe出现在当前目录
lishixinzhi/Article/program/net/201311/11807
如何实现一个简单的RPC框
0,服务接口定义---Echo.java
/** 定义了服务器提供的服务类型 */public interface Echo { public String echo(String string);}
一,客户端代码分析--实现类:MainClient.java
客户端实现包括:获得一个代理对象,并使用该代理对象调用服务器的服务。获取代理对象时,需要指定被代理的类(相当于服务器端提供的服务名),Server IP,Port,这样客户端就能找到服务端的服务了。
延伸:分布式环境下,Client如何打到Server的服务?---因为,在服务器中运行的某些服务不像标准服务有着固定的端口,如HTTP的80端口。
一种解决方法是:在运行服务的每台机器上都运行一个特殊的守护进程,该守护进程负责跟踪位于该机器中每一项服务所使用的端口;此外,守护进程还监听一个特定的已经端口,Client通过这个端口与守护进程联系,请求得到指定服务的端口。
复杂的RPC实现框架中,比如可以把服务注册到ZooKeeper中,Client也从ZooKeeper中查询服务。参考:一个更复杂的RPC框架实现
Echo echo = RPC.getProxy(Echo.class, "127.0.0.1", 20382);System.out.println(echo.echo("hello,hello"));//使用代理对象调用服务器的服务.并将结果输出
二,服务器端分析--实现类:MainServer.java
服务器实现包括:创建一个服务器对象,将它能提供的服务注册,并启动进程监听客户端的连接
Server server = new RPC.RPCServer(); /** server 启动后,需要注册server端能够提供的服务,这样client使用 服务的名字、* 服务器的IP、以及服务所运行的端口 来调用 server 的服务 */server.register(Echo.class, RemoteEcho.class);//注册服务的名字server.register(AnOtherEchoService.class, AnOtherEchoServiceImpl.class);server.start();//启动server
三,服务器监听Client连接分析----实现类:Listener.java
当server.start()后,它要创建一个Listener对象,这是一个线程类,该线程用来监听Client连接。
public void start() {System.out.println("启动服务器");/** server 启动时,需要Listener监听是否有client的请求连接* listener 是一个线程,由它来监听连接 */listener = new Listener(this); this.isRuning = true;listener.start();//listener 是一个线程类,start()后会执行线程的run方法}
其实,监听连接就是JAVA ServerSocket类和Socket类提供的相关功能而已。
/** accept()是一个阻塞方法,server_socket 一直等待client 是否有连接到来 */Socket client = server_socket.accept();//建立一条TCP连接
四,动态代理对象 生成---RPC.java
客户端只需要编写生成代理对象,用代理对象去调用远程服务的代码即可。但是,底层的功能如:建立连接,序列化(本例中也没有考虑),跨语言调用(未考虑)...是由RPC框架完成的。
当MainClient 语句:RPC.getProxy(Echo.class, "127.0.0.1", 20382);执行时,会由
/** @param Class[]{} 该参数声明了动态生成的代理对象实现了的接口,即 clazz 所代表的接口类型 .* 这表明了生成的代理对象它是一个它所实现了的接口类型的对象* 从而就可以用它来调用它所实现的接口中定义的方法** @param handler 生成代理实例对象时需要传递一个handler参数* 这样当该 代理实例对象调用接口中定义的方法时,将会委托给InvocationHandler 接口中声明的invoke方法* 此时,InvocationHandler 的invoke 方法将会被自动调用 */T t = (T) Proxy.newProxyInstance(RPC.class.getClassLoader(), new Class[] {clazz}, handler); return t;
返回该代理对象,然后就会委托第三个参数 handler 自动执行 invoke(),invoke将客户端调用的所有相关信息封装到Invocation 对象中(后面分析)。然后执行第16行代码发起连接。
1 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 2 Invocation invo = new Invocation(); 3 invo.setInterfaces(clazz); 4 5 //利用反射机制将java.lang.reflect.Method 所代表的方法名,参数 封装到 Invocation invo对象中 6 invo.setMethod(new org.jy.rpc.protocal.Method(method.getName(),method.getParameterTypes())); 7 invo.setParams(args); 8 9 /*10 * 当把需要调用的远程server端的方法名和参数封装到invo之后,Client 对象 就可以把 invo 作为参数 传递给服务器了.11 * 为什么需要这样做呢?InvocationHandler 的invoke方法是自动执行的,在该方法里面,它根据生成的代理对象 proxy (第一个参数)12 * 所实现的接口(由 Proxy.newProxyInstance()的第二个参数指定) 就可以知道这个接口中定义了哪些方法13 * InvocationHandler 的 invoke 方法的第二个参数Method method 就可以解析出接口中的方法名和参数了14 * 把它们封装进Invocation invo对象中,再将 invo 作为 client.invoke(invo)的参数 发送到服务器方15 */16 client.invoke(invo);//invoke 先调用init发起一个Socket连接,再将invo 发送至输出流中17 return invo.getResult();18 }
五,“客户端存根”--Client.java
最重要的是它的 invoke方法(注意与InvocationHandler的invoke()区分)。它负责建立连接,打开输入、输出流,向服务器发送字节数据。
1 public void invoke(Invocation invo) throws UnknownHostException, IOException, ClassNotFoundException {2 init();3 System.out.println("写入数据");4 oos.writeObject(invo);//将Client 需要调用的Server的 接口、方法、参数 封装起来 发给服务器5 oos.flush();6 ois = new ObjectInputStream(socket.getInputStream());//用来接收从 server 返回 回来的执行结果 的输入流7 Invocation result = (Invocation) ois.readObject();8 invo.setResult(result.getResult());//将结果 保存到 Invocation result对象中9 }
六,“服务器存根“---实现类:RPCServer.java
上面提到,服务器通过Listener监听客户端连接,当建立客户端连接后,Socket client = server_socket.accept(); 不再阻塞,服务器调用它的call()方法完成客户端请求的功能。也即,客户端请求的结果实际上是在服务器执行生成的。返回的结果是在Client.java 的 invoke() 方法里被读取出来 。call()再一次用到了JAVA反射(第11行) 参考:JAVA动态代理
1 public void call(Invocation invo) { 2 System.out.println(invo.getClass().getName()); 3 Object obj = serviceEngine.get(invo.getInterfaces().getName()); 4 if(obj!=null) { 5 try { 6 Method m = obj.getClass().getMethod(invo.getMethod().getMethodName(), invo.getMethod().getParams()); 7 /* 8 * 利用JAVA反射机制来执行java.lang.reflect.Method 所代表的方法 9 * @param result : 执行实际方法后 得到的 服务的执行结果10 */11 Object result = m.invoke(obj, invo.getParams());12 invo.setResult(result);//将服务的执行结果封装到invo对象中。在后面的代码中,将该对象写入到输出流中13 } catch (Throwable th) {14 th.printStackTrace();15 }16 } else {17 throw new IllegalArgumentException("has no these class");18 }19 }
七,”RPC 编码、解码,协议的定义“---Invocation.java Method.java
其实,这里并不是那种实用的开源RPC框架如Thrift中所指的编码、IDL……上面两个类只是RPC实现过程中辅助完成Java动态代理的实现,说白了就是封装客户端需要调用的方法,然后指定生成的代理对象需要实现的接口(服务).
八,总结:
先运行MainServer.java启动服务器,然后,再运行MainClient.java 启动一个客户端连接服务器就可以看到执行结果。
当需要添加新的服务时:按以下步骤即可:①定义服务接口及其实现类,如:AnOtherEchoService.java ②:在MainServer.java中注册新添加的服务。
③:在MainClient.java中编写获得新服务的代理对象的代码,并用该代理对象调用新服务接口中声明的方法。
这样,在客户端就能够远程地调用服务器上的一个新服务了。
有垃圾回收机制为什么会出现内存溢出
如果分配出去的内存得不到释放,及时回收,就会引起系统运行速度下降,甚至导致程序瘫痪,这就是内存泄露
GC机制
java内存分配和回收 都是jre后台进行, 简称GC机制,
JRE在回收时做了什么
jre 会提供一个后台线程 进行检测和控制, 使用垃圾回收算法进行(1)发现无用信息对象;(2)回收被无用对象占用的内存空间,使该空间可被程序再次使用。
回收的时机一般分为:CPU空闲,内存不足,内存使用极限
垃圾回收机制的缺点,优点,特点,小记
缺点,
无法精确控制垃圾回收的时机和顺序,虚拟机需要跟踪所有对象,确定有用和无用的对象,花费处理器时间,
优点:
不需要花太多时间 解决 存储器问题,缩短开发时间;安全性完整性,GC是一套完整机制
特点,
只能回收无用对象的内存空间,对于物理资源,如数据库链接, 磁盘IO流,网络链接等,等物理类型资源无法释放,需要手动释放处理。
有关函数
一.System.gc()方法
命令行参数透视垃圾收集器的运行
使用System.gc()可以不管JVM使用的是哪一种垃圾回收的算法,都可以请求Java的垃圾回收。
在命令行中有一个参数-verbosegc可以查看Java使用的堆内存的情况,它的格式如下:
java -verbosegc classfile
可以看个例子:
class TestGC
{
public static void main(String[] args)
{
new TestGC();
System.gc();
System.runFinalization();
}
}
1
2
3
4
5
6
7
8
9
10
二. finalize()方法
在JVM垃圾回收器收集一个对象之前,一般要求程序调用适当的方法释放资源,但在没有明确释放资源的情况下,Java提供了缺省机制来终止该对象心释放资源,这个方法就是finalize()。它的原型为:
protected void finalize() throws Throwable
在finalize()方法返回之后,对象消失,垃圾收集开始执行。原型中的throws Throwable表示它可以抛出任何类型的异常。
之所以要使用finalize(),是存在着垃圾回收器不能处理的特殊情况。假定你的对象(并非使用new方法)获得了一块“特殊”的内存区域,由于垃圾回收器只知道那些显示地经由new分配的内存空间,所以它不知道该如何释放这块“特殊”的内存区域,那么这个时候java允许在类中定义一个由finalize()方法。
特殊的区域例如:
1)由于在分配内存的时候可能采用了类似 C语言的做法,而非JAVA的通常new做法。这种情况主要发生在native method中,比如native method调用了C/C++方法malloc()函数系列来分配存储空间,但是除非调用free()函数,否则这些内存空间将不会得到释放,那么这个时候就可能造成内存泄漏。但是由于free()方法是在C/C++中的函数,所以finalize()中可以用本地方法来调用它。以释放这些“特殊”的内存空间。
2)又或者打开的文件资源,这些资源不属于垃圾回收器的回收范围。
1
2
3
4
2)又或者打开的文件资源,这些资源不属于垃圾回收器的回收范围。
换言之,finalize()的主要用途是释放一些其他做法开辟的内存空间,以及做一些清理工作。因为在JAVA中并没有提够像“析构”函数或者类似概念的函数,要做一些类似清理工作的时候,必须自己动手创建一个执行清理工作的普通方法,也就是override Object这个类中的finalize()方法。例如,假设某一个对象在创建过程中会将自己绘制到屏幕上,如果不是明确地从屏幕上将其擦出,它可能永远都不会被清理。如果在finalize()加入某一种擦除功能,当GC工作时,finalize()得到了调用,图像就会被擦除。要是GC没有发生,那么这个图像就会被一直保存下来。
一旦垃圾回收器准备好释放对象占用的存储空间,首先会去调用finalize()方法进行一些必要的清理工作。只有到下一次再进行垃圾回收动作的时候,才会真正释放这个对象所占用的内存空间。
在普通的清除工作中,为清除一个对象,那个对象的用户必须在希望进行清除的地点调用一个清除方法。这与C++”析构函数”的概念稍有抵触。在C++中,所有对象都会破坏(清除)。或者换句话说,所有对象都”应该”破坏。若将C++对象创建成一个本地对象,比如在堆栈中创建(在Java中是不可能的,Java都在堆中),那么清除或破坏工作就会在”结束花括号”所代表的、创建这个对象的作用域的末尾进行。若对象是用new创建的(类似于Java),那么当程序员调用C++的 delete命令时(Java没有这个命令),就会调用相应的析构函数。若程序员忘记了,那么永远不会调用析构函数,我们最终得到的将是一个内存”漏洞”,另外还包括对象的其他部分永远不会得到清除。
相反,Java不允许我们创建本地(局部)对象–无论如何都要使用new。但在Java中,没有”delete”命令来释放对象,因为垃圾回收器会帮助我们自动释放存储空间。所以如果站在比较简化的立场,我们可以说正是由于存在垃圾回收机制,所以Java没有析构函数。然而,随着以后学习的深入,就会知道垃圾收集器的存在并不能完全消除对析构函数的需要,或者说不能消除对析构函数代表的那种机制的需要(原因见下一段。另外finalize()函数是在垃圾回收器准备释放对象占用的存储空间的时候被调用的,绝对不能直接调用finalize(),所以应尽量避免用它)。若希望执行除释放存储空间之外的其他某种形式的清除工作,仍然必须调用Java中的一个方法。它等价于C++的析构函数,只是没后者方便。
在C++中所有的对象运用delete()一定会被销毁,而JAVA里的对象并非总会被垃圾回收器回收。In another word, 1 对象可能不被垃圾回收,2 垃圾回收并不等于“析构”,3 垃圾回收只与内存有关。也就是说,并不是如果一个对象不再被使用,是不是要在finalize()中释放这个对象中含有的其它对象呢?不是的。因为无论对象是如何创建的,垃圾回收器都会负责释放那些对象占有的内存。
在这个例子中,一个新的对象被创建,由于它没有使用,所以该对象迅速地变为不可达,程序编译后,执行命令: java -verbosegc TestGC 后结果为:
[Full GC 168K->97K(1984K), 0.0253873 secs]
机器的环境为,Windows 2000 + JDK1.3.1,箭头前后的数据168K和97K分别表示垃圾收集GC前后所有存活对象使用的内存容量,说明有168K-97K=71K的对象容量被回收,括号内的数据1984K为堆内存的总容量,收集所需要的时间是0.0253873秒(这个时间在每次执行的时候会有所不同)。
需要注意的是,调用System.gc()也仅仅是一个请求(建议)。JVM接受这个消息后,并不是立即做垃圾回收,而只是对几个垃圾回收算法做了加权,使垃圾回收操作容易发生,或提早发生,或回收较多而已。
update
@11/18
一. jvm 内存 结构图
这里写图片描述
存储器
VM内存结构由堆、栈、本地方法栈、方法区等部分组成,另外JVM分别对新生代和旧生代采用不同的垃圾回收机制。
二.如何确定某个对象是“垃圾”?
我们先了解一个最基本的问题:如果确定某个对象是“垃圾”?既然垃圾收集器的任务是回收垃圾对象所占的空间供新的对象使用,那么垃圾收集器如何确定某个对象是“垃圾”?—即通过什么方法判断一个对象可以被回收了。
在java中是通过引用来和对象进行关联的,也就是说如果要操作对象,必须通过引用来进行。那么很显然一个简单的办法就是通过引用计数来判断一 个对象是否可以被回收。不失一般性,如果一个对象没有任何引用与之关联,则说明该对象基本不太可能在其他地方被使用到,那么这个对象就成为可被回收的对象 了。这种方式成为引用计数法。
这种方式的特点是实现简单,而且效率较高,但是它无法解决循环引用的问题,因此在Java中并没有采用这种方式(Python采用的是引用计数法)。看下面这段代码:
public class Main {
public static void main(String[] args) {
MyObject object1 = new MyObject();
MyObject object2 = new MyObject();
object1.object = object2;
object2.object = object1;
object1 = null;
object2 = null;
}
}
class MyObject{
public Object object = null;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
最后面两句将object1和object2赋值为null,也就是说object1和object2指向的对象已经不可能再被访问,但是由于它们互相引用对方,导致它们的引用计数都不为0,那么垃圾收集器就永远不会回收它们。
为了解决这个问题,在Java中采取了 可达性分析法。该方法的基本思想是通过一系列的“GC Roots”对象作为起点进行搜索,如果在“GC Roots”和一个对象之间没有可达路径,则称该对象是不可达的,不过要注意的是被判定为不可达的对象不一定就会成为可回收对象。被判定为不可达的对象要 成为可回收对象必须至少经历两次标记过程,如果在这两次标记过程中仍然没有逃脱成为可回收对象的可能性,则基本上就真的成为可回收对象了。
至于可达性分析法具体是如何操作的我暂时也没有看得很明白,如果有哪位朋友比较清楚的话请不吝指教。
下面来看个例子:
Object aobj = new Object ( ) ;
Object bobj = new Object ( ) ;
Object cobj = new Object ( ) ;
aobj = bobj;
aobj = cobj;
cobj = null;
aobj = null
1
2
3
4
5
6
7
第几行有可能会使得某个对象成为可回收对象?第7行的代码会导致有对象会成为可回收对象。至于为什么留给读者自己思考。
再看一个例子:
String str = new String("hello");
SoftReference
sr = new SoftReference
(new String("java"));
WeakReference
wr = new WeakReference
(new String("world"));
1
2
3
这三句哪句会使得String对象成为可回收对象?
答:第2句和第3句,第2句在内存不足的情况下会将String对象判定为可回收对象,第3句无论什么情况下String对象都会被判定为可回收对象。
最后总结一下平常遇到的比较常见的将对象判定为可回收对象的情况:
1)显示地将某个引用赋值为null或者将已经指向某个对象的引用指向新的对象,比如下面的代码:
Object obj = new Object();
obj = null;
Object obj1 = new Object();
Object obj2 = new Object();
obj1 = obj2;
1
2
3
4
5
6
2)局部引用所指向的对象,比如下面这段代码:
void fun() {
.....
for(int i=0;i<10;i++) {
Object obj = new Object();
System.out.println(obj.getClass());
}
}
1
2
3
4
5
6
7
8
9
循环每执行完一次,生成的Object对象都会成为可回收的对象。
3)只有弱引用与其关联的对象,比如:
WeakReference wr = new WeakReference(new String(“world”));
1
三.触发主GC(Garbage Collector)的条件
JVM进行次GC的频率很高,但因为这种GC占用时间极短,所以对系统产生的影响不大。更值得关注的是主GC的触发条件,因为它对系统影响很明显。总的来说,有两个条件会触发主GC:
1)当应用程序空闲时,即没有应用线程在运行时,GC会被调用。因为GC在优先级最低的线程中进行,所以当应用忙时,GC线程就不会被调用,但以下条件除外。
2)Java堆内存不足时,GC会被调用。当应用线程在运行,并在运行过程中创建新对象,若这时内存空间不足,JVM就会强制地调用GC线程,以便回收内存用于新的分配。若GC一次之后仍不能满足内存分配的要求,JVM会再进行两次GC作进一步的尝试,若仍无法满足要求,则 JVM将报“out of memory”的错误,Java应用将停止。
由于是否进行主GC由JVM根据系统环境决定,而系统环境在不断的变化当中,所以主GC的运行具有不确定性,无法预计它何时必然出现,但可以确定的是对一个长期运行的应用来说,其主GC是反复进行的。
四.减少GC开销的措施
根据上述GC的机制,程序的运行会直接影响系统环境的变化,从而影响GC的触发。若不针对GC的特点进行设计和编码,就会出现内存驻留等一系列负面影响。为了避免这些影响,基本的原则就是尽可能地减少垃圾和减少GC过程中的开销。具体措施包括以下几个方面:
(1)不要显式调用System.gc()
此函数建议JVM进行主GC,虽然只是建议而非一定,但很多情况下它会触发主GC,从而增加主GC的频率,也即增加了间歇性停顿的次数。
(2)尽量减少临时对象的使用
临时对象在跳出函数调用后,会成为垃圾,少用临时变量就相当于减少了垃圾的产生,从而延长了出现上述第二个触发条件出现的时间,减少了主GC的机会。
(3)对象不用时最好显式置为Null
一般而言,为Null的对象都会被作为垃圾处理,所以将不用的对象显式地设为Null,有利于GC收集器判定垃圾,从而提高了GC的效率。
(4)尽量使用StringBuffer,而不用String来累加字符串
由于String是固定长的字符串对象,累加String对象时,并非在一个String对象中扩增,而是重新创建新的String对象,如Str5=Str1+Str2+Str3+Str4,这条语句执行过程中会产生多个垃圾对象,因为对次作“+”操作时都必须创建新的String对象,但这些过渡对象对系统来说是没有实际意义的,只会增加更多的垃圾。避免这种情况可以改用StringBuffer来累加字符串,因StringBuffer是可变长的,它在原有基础上进行扩增,不会产生中间对象。
(5)能用基本类型如Int,Long,就不用Integer,Long对象
基本类型变量占用的内存资源比相应对象占用的少得多,如果没有必要,最好使用基本变量。
(6)尽量少用静态对象变量
静态变量属于全局变量,不会被GC回收,它们会一直占用内存。
(7)分散对象创建或删除的时间
集中在短时间内大量创建新对象,特别是大对象,会导致突然需要大量内存,JVM在面临这种情况时,只能进行主GC,以回收内存或整合内存碎片,从而增加主GC的频率。集中删除对象,道理也是一样的。它使得突然出现了大量的垃圾对象,空闲空间必然减少,从而大大增加了下一次创建新对象时强制主GC的机会。
五. 关于垃圾回收的几点补充
经过上述的说明,可以发现垃圾回收有以下的几个特点:3
(1)垃圾收集发生的不可预知性:由于实现了不同的垃圾回收算法和采用了不同的收集机制,所以它有可能是定时发生,有可能是当出现系统空闲CPU资源时发生,也有可能是和原始的垃圾收集一样,等到内存消耗出现极限时发生,这与垃圾收集器的选择和具体的设置都有关系。
(2)垃圾收集的精确性:主要包括2 个方面:(a)垃圾收集器能够精确标记活着的对象;(b)垃圾收集器能够精确地定位对象之间的引用关系。前者是完全地回收所有废弃对象的前提,否则就可能造成内存泄漏。而后者则是实现归并和复制等算法的必要条件。所有不可达对象都能够可靠地得到回收,所有对象都能够重新分配,允许对象的复制和对象内存的缩并,这样就有效地防止内存的支离破碎。
(3)现在有许多种不同的垃圾收集器,每种有其算法且其表现各异,既有当垃圾收集开始时就停止应用程序的运行,又有当垃圾收集开始时也允许应用程序的线程运行,还有在同一时间垃圾收集多线程运行。
(4)垃圾收集的实现和具体的JVM 以及JVM的内存模型有非常紧密的关系。不同的JVM 可能采用不同的垃圾收集,而JVM 的内存模型决定着该JVM可以采用哪些类型垃圾收集。现在,HotSpot 系列JVM中的内存系统都采用先进的面向对象的框架设计,这使得该系列JVM都可以采用最先进的垃圾收集。
(5)随着技术的发展,现代垃圾收集技术提供许多可选的垃圾收集器,而且在配置每种收集器的时候又可以设置不同的参数,这就使得根据不同的应用环境获得最优的应用性能成为可能。
针对以上特点,我们在使用的时候要注意:
(1)不要试图去假定垃圾收集发生的时间,这一切都是未知的。比如,方法中的一个临时对象在方法调用完毕后就变成了无用对象,这个时候它的内存就可以被释放。
(2)Java中提供了一些和垃圾收集打交道的类,而且提供了一种强行执行垃圾收集的方法–调用System.gc(),但这同样是个不确定的方法。Java 中并不保证每次调用该方法就一定能够启动垃圾收集,它只不过会向JVM发出这样一个申请,到底是否真正执行垃圾收集,一切都是个未知数。
(3)挑选适合自己的垃圾收集器。一般来说,如果系统没有特殊和苛刻的性能要求,可以采用JVM的缺省选项。否则可以考虑使用有针对性的垃圾收集器,比如增量收集器就比较适合实时性要求较高的系统之中。系统具有较高的配置,有比较多的闲置资源,可以考虑使用并行标记/清除收集器。
(4)关键的也是难把握的问题是内存泄漏。良好的编程习惯和严谨的编程态度永远是最重要的,不要让自己的一个小错误导致内存出现大漏洞。
(5)尽早释放无用对象的引用。大多数程序员在使用临时变量的时候,都是让引用变量在退出活动域(scope)后,自动设置为null,暗示垃圾收集器来收集该对象,还必须注意该引用的对象是否被监听,如果有,则要去掉监听器,然后再赋空值。
六.垃圾回收机制的意义
在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象;而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾。JVM的一个系统级线程会自动释放该内存块。垃圾回收意味着程序不再需要的对象是”无用信息”,这些信息将被丢弃。当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用。事实上,除了释放没用的对象,垃圾回收也可以清除内存记录碎片。由于创建对象和垃圾回收器释放丢弃对象所占的内存空间,内存会出现碎片。碎片是分配给对象的内存块之间的空闲内存洞。碎片整理将所占用的堆内存移到堆的一端,JVM将整理出的内存分配给新的对象。
垃圾回收能自动释放内存空间,减轻编程的负担。这使Java 虚拟机具有一些优点。首先,它能使编程效率提高。在没有垃圾回收机制的时候,可能要花许多时间来解决一个难懂的存储器问题。在用Java语言编程的时候,靠垃圾回收机制可大大缩短时间。其次是它保护程序的完整性, 垃圾回收是Java语言安全性策略的一个重要部份。
垃圾回收的一个潜在的缺点是它的开销影响程序性能。Java虚拟机必须追踪运行程序中有用的对象,而且最终释放没用的对象。这一个过程需要花费处理器的时间。其次垃圾回收算法的不完备性,早先采用的某些垃圾回收算法就不能保证100%收集到所有的废弃内存。当然随着垃圾回收算法的不断改进以及软硬件运行效率的不断提升,这些问题都可以迎刃而解。
你没有开自动回收啊!
C#中排序问题,将一个list中对象的某个值排序,返回值最大的那个对象,程序没有结果,哪位高人帮忙看看啊
1、如果只是返回最大的那个值就不需要排序。
2、如果是对象排序请不要修改对象的属性,你这排次序还把所有对象属性都变了,太有才了。
只是返回最大值很简单:一次冒泡就搞定了!
你这样写有点多此一举,
num1 = vectorInforms[i].综合效用值;
num2 = vectorInforms[i + 1].综合效用值;
if (num1
<num2)
{
Swap( ref num1, ref num2);
isOK = false;
}
你这里只是做了比较,并没有将值真正的互换,如果你真要在你的基础上改,就改成这样吧:
public static VectorInform Sort(List
vectorInforms)//冒泡排序
{
VectorInform vectorInform = new VectorInform();//定义的对象
//int num1, num2;
bool isOK = false;
int iterateCount = 0;
while (!isOK)
{
isOK = true;
for (int i = 0; i < vectorInforms.Count - 1; i++)
{
iterateCount++;
//num1 = vectorInforms[i].Value;//综合效用值;
//num2 = vectorInforms[i + 1].Value;//综合效用值;
if (vectorInforms[i].Value > vectorInforms[i + 1].Value)
{
int c = vectorInforms[i].Value;
vectorInforms[i].Value = vectorInforms[i + 1].Value;
vectorInforms[i + 1].Value = c;
isOK = false;
}
vectorInform = vectorInforms[i + 1];
}
}
return vectorInform;
}
更简单的就是:
VectorInform vectorInform =vectorInforms[0];
for (int i= 1; i < vectorInforms.Count ; i++)
{
if (vectorInform.Value
<vectorinforms[i].value )
{
vectorInform = vectorInforms[i];
}
}
return vectorInform
list对象排序不需要自己写sort方法啊,如果是List
要排序的话,继承IComparer
,实现compare方法再调用list.sort方法就可以啊
我这个是使用List
.Sort排序取值:
如下
public VectorInform Sort(List
vectorInforms)
{
vectorInforms.Sort(new Comparison
(VectorInformCompare));
return vectorInforms[0];
}
public int VectorInformCompare(VectorInform v1, VectorInform v2)
{
return Math.Sign(v2.综合效用值 - v1.综合效用值);
}
1.面向对象的软件开发有哪些优点?
1)把软件系统看成是各种对象的集合,这更接近人的思维。
2)软件需求的变动往往是功能的变动,而功能的执行者--对象一般不会有太大的变化。这使得按照对象设计出来的系统结构比较稳定。
3)对象包括属性和方法,对象把属性和方法的具体实现方式一起封装起来,这使得方法与之相关的属性不再分离,提高每个子系统的相对独立性,从而提高了软件的可维护性。
4)支持封装、继承、多态和抽象,提高了软件的可重用性、可维护性和可扩展性。
2.把一个类放在包里有什么作用?(包的作用)
1)能够区分名字相同的类。
2)有助于实施访问权限控制。
3)有助于划分和组织java应用中的各个类。
3.说出一些常用的类,包,接口,请各举出5个。
Runable,ActionListener,Conllection,Map,Set,List接口
1)java.lang包----包括线程类(Thread)、异常类(Exception)、系统类(System)、整数类(Integer)和字符串类(String) 等, 这些类是java程序中经常用到的。
2)java.awt包----抽象窗口工具箱包,awt是(Abstract Window Toolkit) 的缩写。这个包中包含了用于构建GUI界面的类及绘图类。
3)java.io包----输入/输出包,包含各种输入流类和输出流类,如文件输入流类(FileInputStream类)及文件输出流类(FileOutputStream)等。
4)java.util包----提供一些实用类,如日期类(Data)和集合类(Collection)等。
5)java.net包----支持TCP/IP网络协议,包括Socket类及和URL相关的类,这些类都用于网络编程。
除了上面提到的基本包,JDK中还有很多其他包,比如用于数据库编程的java.sql包,用于编写网络程序的java.rmi包(rmi是“Remote Method Invocation”的缩写)。另外,javax.*包是对基本包的扩展,包括用于编写GUI的javax.Swing包,以及用于编写声音程序的javax.sound包等。
4. 描述一下你最常用的编程风格。
1)注意编码规则,符合编码要求。
2)变量,类等起名要有意义。
3)经常格式化代码,注意格式。
4)代码中加入测试方法或测试类,尽量提早发现错误。
5)代码中要加入注释,为别人和自己将来理解代码带来方便。
5. 说一说标识符的命名规则,以及java的编程规范。
Java标识符的命名规则:
1) 标识符由字母、数字、下划线“_”、美元符号“$”或者人民币符号“¥”组成,并且首字母不能是数字。
2) 不能把关键字和保留字作为标识符。
3) 标识符没有长度限制。
4) 标识符对大小写敏感。
Java编程规范:
1)类名和接口名:首字母大写,其余字母小写。如SamDoc
2)方法名和变量名:首字母小写,其余的字母大写。
如bothEyesOfDoll。
3)包名:字母全部小写。如,com.abc.dollapp。
4)常量名:采用大写形式,单词之间以下划线“_”隔开。
如DEFAULT_COLOR_DOL。
…………………………
31、介绍JAVA中的Collection FrameWork(包括如何写自己的数据结构)?
答:Collection FrameWork如下:
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)
Map提供key到value的映射
32、抽象类与接口?
答:抽象类与接口都用于抽象,但是抽象类(JAVA中)可以有自己的部分实现,而接口则完全是一个标识(同时有多重继承的功能)。
JAVA类实现序例化的方法是实现java.io.Serializable接口
Collection框架中实现比较要实现Comparable 接口和 Comparator 接口
33、STRING与STRINGBUFFER的区别。
答:STRING的长度是不可变的,STRINGBUFFER的长度是可变的。如果你对字符串中的内容经常进行操作,特别是内容要修改时,那么使用StringBuffer,如果最后需要String,那么使用StringBuffer的toString()方法
34、谈谈final, finally, finalize的区别
答:final?修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载
finally?再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)
finalize?方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的
35、面向对象的特征有哪些方面
答:主要有以下四方面:
1.抽象:
抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。
2.继承:
继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。
3.封装:
封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。
4. 多态性:
多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。
36、String是最基本的数据类型吗
答:基本数据类型包括byte、int、char、long、float、double、boolean和short。
java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类
37、int 和 Integer 有什么区别
答:Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。原始类型封装类booleanBoolean,charCharacter,byteByte,shortShort,intInteger,
longLong,floatFloat,doubleDouble
引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关
38、运行时异常与一般异常有何异同
答:异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。
39、说出ArrayList,Vector, LinkedList的存储性能和特性
答:ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,
Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。
40、HashMap和Hashtable的区别
答:HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。
HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。
HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。
Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。
Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。
41、heap和stack有什么区别
答:栈是一种线形集合,其添加和删除元素的操作应在同一段完成。栈按照后进先出的方式进行处理。堆是栈的一个组成元素
42、Java的接口和C++的虚类的相同和不同处
答:由于Java不支持多继承,而有可能某个类或对象要使用分别在几个类或对象里面的方法或属性,现有的单继承机制就不能满足要求。与继承相比,接口有更高的灵活性,因为接口中没有任何实现代码。当一个类实现了接口以后,该类要实现接口里面所有的方法和属性,并且接口里面的属性在默认状态下面都是public static,所有方法默认情况下是public.一个类可以实现多个接口。
43、Java中的异常处理机制的简单原理和应用
答:当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常。违反语义规则包括2种情况。一种是JAVA类库内置的语义检查。例如数组下标越界,会引发IndexOutOfBoundsException;访问null的对象时会引发NullPointerException。另一种情况就是JAVA允许程序员扩展这种语义检查,程序员可以创建自己的异常,并自由选择在何时用throw关键字引发异常。所有的异常都是java.lang.Thowable的子类。
43、垃圾回收的优点和原理。并考虑2种回收机制
答:Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有"作用域"的概念,只有对象的引用才有"作用域"。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。
44、你所知道的集合类都有哪些?主要方法?
答:最常用的集合类是 List 和 Map。 List 的具体实现包括 ArrayList 和 Vector,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象的元素列表。 List 适用于按数值索引访问元素的情形。
Map 提供了一个更通用的元素存储方法。 Map 集合类用于存储元素对(称作"键"和"值"),其中每个键映射到一个值。
45、描述一下JVM加载class文件的原理机制?
答:JVM中类的装载是由ClassLoader和它的子类来实现的,Java ClassLoader 是一个重要的Java运行时系统组件。它负责在运行时查找和装入类文件的类。
46、排序都有哪几种方法?请列举
答: 排序的方法有:插入排序(直接插入排序、希尔排序),交换排序(冒泡排序、快速排序),选择排序(直接选择排序、堆排序),归并排序,分配排序(箱排序、基数排序)
快速排序的伪代码。
/ /使用快速排序方法对a[ 0 :n- 1 ]排序
从a[ 0 :n- 1 ]中选择一个元素作为middle,该元素为支点
把余下的元素分割为两段left 和right,使得left中的元素都小于等于支点,而right 中的元素都大于等于支点
递归地使用快速排序方法对left 进行排序
递归地使用快速排序方法对right 进行排序
所得结果为left + middle + right
47、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?="3">答:Java通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在Java中,每个异常都是一个对象,它是Throwable类或其它子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。Java的异常处理是通过5个关键词来实现的:try、catch、throw、throws和finally。一般情况下是用try来执行一段程序,如果出现异常,系统会抛出(throws)一个异常,这时候你可以通过它的类型来捕捉(catch)它,或最后(finally)由缺省处理器来处理。
用try来指定一块预防所有"异常"的程序。紧跟在try程序后面,应包含一个catch子句来指定你想要捕捉的"异常"的类型。
throw语句用来明确地抛出一个"异常"。
throws用来标明一个成员函数可能抛出的各种"异常"。
Finally为确保一段代码不管发生什么"异常"都被执行一段代码。
可以在一个成员函数调用的外面写一个try语句,在这个成员函数内部写另一个try语句保护其他代码。每当遇到一个try语句,"异常"的框架就放到堆栈上面,直到所有的try语句都完成。如果下一级的try语句没有对某种"异常"进行处理,堆栈就会展开,直到遇到有处理这种"异常"的try语句。
48、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?
答:可以。必须只有一个类名与文件名相同。
49、java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
答:字节流,字符流。字节流继承于InputStream OutputStream,字符流继承于InputStreamReader OutputStreamWriter。在java.io包中还有许多其他的流,主要是为了提高性能和使用方便。
50、java中会存在内存泄漏吗,请简单描述。
答:会。自己实现堆载的数据结构时有可能会出现内存泄露,可参看effective java.
</num2)
log4j 支持环境变量吗
修改 log4j 代码 以支持在 log4j.properties 设置环境变量
http://logging.apache.org/site/binindex.cgi
对源码进行浏览后,估计需要修改的文件应该是
src\java\org\apache\log4j\helpers\OptionConverter.java
在这个文件可以看到,log4j 对 ${} 这种形式的变量会进行以下转换
// first try in System properties
String replacement = getSystemProperty(key, null);
// then try props parameter
if(replacement == null && props != null) {
replacement = props.getProperty(key);
}
就是说,会先从系统变量中读取属性值,如果系统变量不存在这个属性,就从log4j配置文件中属性中读取.
问题就在这里了!
并没有从环境变量中读取,因此,增加一个函数:
public
static
String getEnvProperty(String key, String def) {
try {
String value = System.getenv(key);
if (value == null)
value = def;
return value;
} catch(Throwable e) { // MS-Java throws com.ms.security.SecurityExceptionEx
LogLog.debug("Was not allowed to read system property \""+key+"\".");
return def;
}
}
是的,通过调用 System.getenv() ,就可以从环境变量中读取属性值了.
再修改刚才的代码
// first try in System properties
String replacement = getSystemProperty(key, null);
// then try in environment properties
if (replacement == null)
{
replacement = getEnvProperty(key, null);
}
// then try props parameter
if(replacement == null && props != null) {
replacement = props.getProperty(key);
}
ok, 代码修改工作完毕, 现在需要编译了.(当然,你需要先安装 ant 和 java. 以后我贴相应的安装文档出来.)
在 logging-log4j-1.2.11 目录下输入
ant
会提示要加参数,所以改为输入
ant build
编译通过,但发现有其它问题,不过不要紧了,已经有这个文件就可以了
logging-log4j-1.2.11\dist\classes\org\apache\log4j\helpers\OptionConverter.class
要正常生成 jar 文件,可能需要其它库文件支持,但不是我研究的方向了.
我只要把这个 OptionConverter.class 放到 log4j-1.2.11.jar 文件里, 替换掉旧的 OptionConverter.class 就可以了.
howto? easy job. 用 winrar 打开 log4j-1.2.11.jar, 用新的 OptionConverter.class 覆盖掉旧的, done!
最后一步, 把这个新的log4j-1.2.11.jar 布署到你的系统中,就可以了.
或者改一个名字? log4j-1.2.11-pro.jar ? 增强版~ 咔咔, well done!