1. 反射机制是什么
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
2. 反射机制能做什么
反射机制主要提供了以下功能:
在运行时判断任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法;
在运行时调用任意一个对象的方法;
生成动态代理。
3. 反射机制的相关API
通过一个对象获得完整的包名和类名
package net.xsoftlab.baikepublic class TestReflect {
public static void main(String[] args) throws Exception {
TestReflect testReflect = new TestReflect()
System.out.println(testReflect.getClass().getName())
// 结果 net.xsoftlab.baike.TestReflect
}
}
实例化Class类对象
package net.xsoftlab.baikepublic class TestReflect {
public static void main(String[] args) throws Exception {
Class<?> class1 = null
Class<?> class2 = null
Class<?> class3 = null
// 一般采用这种形式
class1 = Class.forName("net.xsoftlab.baike.TestReflect")
class2 = new TestReflect().getClass()
class3 = TestReflect.class
System.out.println("类名称 " + class1.getName())
System.out.println("类名称 " + class2.getName())
System.out.println("类名称 " + class3.getName())
}
}
获取一个对象的父类与实现的接口
package net.xsoftlab.baikeimport java.io.Serializable
public class TestReflect implements Serializable {
private static final long serialVersionUID = -2862585049955236662L
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("net.xsoftlab.baike.TestReflect")
// 取得父类
Class<?> parentClass = clazz.getSuperclass()
System.out.println("clazz的父类为:" + parentClass.getName())
// clazz的父类为: java.lang.Object
// 获取所有的接口
Class<?> intes[] = clazz.getInterfaces()
System.out.println("clazz实现的接口有:")
for (int i = 0 i < intes.length i++) {
System.out.println((i + 1) + ":" + intes[i].getName())
}
// clazz实现的接口有:
// 1:java.io.Serializable
}
}
获取某个类中的全部构造函数 - 详见下例
通过反射机制实例化一个类的对象
package net.xsoftlab.baikeimport java.lang.reflect.Constructor
public class TestReflect {
public static void main(String[] args) throws Exception {
Class<?> class1 = null
class1 = Class.forName("net.xsoftlab.baike.User")
// 第一种方法,实例化默认构造方法,调用set赋值
User user = (User) class1.newInstance()
user.setAge(20)
user.setName("Rollen")
System.out.println(user)
// 结果 User [age=20, name=Rollen]
// 第二种方法 取得全部的构造函数 使用构造函数赋值
Constructor<?> cons[] = class1.getConstructors()
// 查看每个构造方法需要的参数
for (int i = 0 i < cons.length i++) {
Class<?> clazzs[] = cons[i].getParameterTypes()
System.out.print("cons[" + i + "] (")
for (int j = 0 j < clazzs.length j++) {
if (j == clazzs.length - 1)
System.out.print(clazzs[j].getName())
else
System.out.print(clazzs[j].getName() + ",")
}
System.out.println(")")
}
// 结果
// cons[0] (java.lang.String)
// cons[1] (int,java.lang.String)
// cons[2] ()
user = (User) cons[0].newInstance("Rollen")
System.out.println(user)
// 结果 User [age=0, name=Rollen]
user = (User) cons[1].newInstance(20, "Rollen")
System.out.println(user)
// 结果 User [age=20, name=Rollen]
}
}
class User {
private int age
private String name
public User() {
super()
}
public User(String name) {
super()
this.name = name
}
public User(int age, String name) {
super()
this.age = age
this.name = 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
}
@Override
public String toString() {
return "User [age=" + age + ", name=" + name + "]"
}
}
获取某个类的全部属性
package net.xsoftlab.baikeimport java.io.Serializable
import java.lang.reflect.Field
import java.lang.reflect.Modifier
public class TestReflect implements Serializable {
private static final long serialVersionUID = -2862585049955236662L
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("net.xsoftlab.baike.TestReflect")
System.out.println("===============本类属性===============")
// 取得本类的全部属性
Field[] field = clazz.getDeclaredFields()
for (int i = 0 i < field.length i++) {
// 权限修饰符
int mo = field[i].getModifiers()
String priv = Modifier.toString(mo)
// 属性类型
Class<?> type = field[i].getType()
System.out.println(priv + " " + type.getName() + " " + field[i].getName() + "")
}
System.out.println("==========实现的接口或者父类的属性==========")
// 取得实现的接口或者父类的属性
Field[] filed1 = clazz.getFields()
for (int j = 0 j < filed1.length j++) {
// 权限修饰符
int mo = filed1[j].getModifiers()
String priv = Modifier.toString(mo)
// 属性类型
Class<?> type = filed1[j].getType()
System.out.println(priv + " " + type.getName() + " " + filed1[j].getName() + "")
}
}
}
通过反射机制调用某个类的方法
package net.xsoftlab.baikeimport java.lang.reflect.Method
public class TestReflect {
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("net.xsoftlab.baike.TestReflect")
// 调用TestReflect类中的reflect1方法
Method method = clazz.getMethod("reflect1")
method.invoke(clazz.newInstance())
// Java 反射机制 - 调用某个类的方法1.
// 调用TestReflect的reflect2方法
method = clazz.getMethod("reflect2", int.class, String.class)
method.invoke(clazz.newInstance(), 20, "张三")
// Java 反射机制 - 调用某个类的方法2.
// age -> 20. name -> 张三
}
public void reflect1() {
System.out.println("Java 反射机制 - 调用某个类的方法1.")
}
public void reflect2(int age, String name) {
System.out.println("Java 反射机制 - 调用某个类的方法2.")
System.out.println("age -> " + age + ". name -> " + name)
}
}
通过反射机制操作某个类的属性
package net.xsoftlab.baikeimport java.lang.reflect.Field
public class TestReflect {
private String proprety = null
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("net.xsoftlab.baike.TestReflect")
Object obj = clazz.newInstance()
// 可以直接对 private 的属性赋值
Field field = clazz.getDeclaredField("proprety")
field.setAccessible(true)
field.set(obj, "Java反射机制")
System.out.println(field.get(obj))
}
}
4. 反射机制的应用实例
在泛型为Integer的ArrayList中存放一个String类型的对象。
package net.xsoftlab.baikeimport java.lang.reflect.Method
import java.util.ArrayList
public class TestReflect {
public static void main(String[] args) throws Exception {
ArrayList<Integer> list = new ArrayList<Integer>()
Method method = list.getClass().getMethod("add", Object.class)
method.invoke(list, "Java反射机制实例。")
System.out.println(list.get(0))
}
}
通过反射取得并修改数组的信息
package net.xsoftlab.baikeimport java.lang.reflect.Array
public class TestReflect {
public static void main(String[] args) throws Exception {
int[] temp = { 1, 2, 3, 4, 5 }
Class<?> demo = temp.getClass().getComponentType()
System.out.println("数组类型: " + demo.getName())
System.out.println("数组长度 " + Array.getLength(temp))
System.out.println("数组的第一个元素: " + Array.get(temp, 0))
Array.set(temp, 0, 100)
System.out.println("修改之后数组第一个元素为: " + Array.get(temp, 0))
}
}
将反射机制应用于工厂模式
package net.xsoftlab.baikeinterface fruit {
public abstract void eat()
}
class Apple implements fruit {
public void eat() {
System.out.println("Apple")
}
}
class Orange implements fruit {
public void eat() {
System.out.println("Orange")
}
}
class Factory {
public static fruit getInstance(String ClassName) {
fruit f = null
try {
f = (fruit) Class.forName(ClassName).newInstance()
} catch (Exception e) {
e.printStackTrace()
}
return f
}
}
/**
* 对于普通的工厂模式当我们在添加一个子类的时候,就需要对应的修改工厂类。 当我们添加很多的子类的时候,会很麻烦。
* Java 工厂模式可以参考
* http://baike.xsoftlab.net/view/java-factory-pattern
*
* 现在我们利用反射机制实现工厂模式,可以在不修改工厂类的情况下添加任意多个子类。
*
* 但是有一点仍然很麻烦,就是需要知道完整的包名和类名,这里可以使用properties配置文件来完成。
*
* java 读取 properties 配置文件 的方法可以参考
* http://baike.xsoftlab.net/view/java-read-the-properties-configuration-file
*
* @author xsoftlab.net
*/
public class TestReflect {
public static void main(String[] args) throws Exception {
fruit f = Factory.getInstance("net.xsoftlab.baike.Apple")
if (f != null) {
f.eat()
}
}
} 我有一个微信公众号,经常会分享一些Java技术相关的干货,还有一些学习资源。
如果你喜欢我的分享,可以用微信搜索“Java团长”或者“javatuanzhang”关注。
宝石(Stone)
钻石 Diamond
红宝石 Ruby
蓝宝石 Sapphire
绿柱石 Beryl
锆石 Zircon
橄榄石 Peridot
翡翠 Jadeite
绿松石 Turquoise
托帕石 Topaz
珊瑚 Coral
琥珀 Amber
象牙 Ivory
祖母绿 Emerald
坦桑石Tanzanite
碧玺 Tourmaline
石榴石 Garnet
石英 Quartz
水晶 Crystal
粉晶 Rose
孔雀石 Malachite
大理石 Marble
贝壳 Shell
闪山灵 Opal
缟玛瑙 Onyx
欧泊 Opal
葡萄石 Prehnite
珍珠 Pearl
紫晶 Amethyst
黄晶 Citrine
琥珀 Amber
寿山石 Lardetite
珍珠 Pearl
形状(Shape)
圆形 Round
锥形 Taper
马眼形 Marquise
梨形 Pear
长方形 Rectangle
椭圆形 Oval
心形 Heart
八角形 Octagon
正方形 Square
半圆形 Semicircle
类型(Type)
戒指 Ring
耳环 Earring
吊坠 Pendant
手镯 Bangle
手链 Bracelet
项链 Necklace
呔针 Tie Pin
呔链 Tie Chain
呔钉 Tie Tack
夹子 Clip
套装 Set
袖口钮 Cufflinks
发夹 Hair Clip
框 Frame
笔夹 Pen Clip
金币 Gold Coin
胸针 Brooch
雕刻品 Carving
扣掣 Snap
表 Watch
相盒 Locket
封底片 Plate
瓜子耳 Bails
配件 Parts
链 Chain
珠子 Bead
扣子 Clasp
踝饰 Anklet
一串 Strand
款式 Style
镶嵌(Setting)
针板镶座 Barsetting
包镶 Bezelsetting
夹镶 Channelsetting
群镶 Clustersetting
隐藏式镶嵌Invisible
密镶式镶 Pavesetting
爪镶 Prongsetting
座单石镶 Solitairesetting
吉普赛镶 Gypsysetting
帝凡尼镶 Tiffanysetting
金属(Metal)
黄金 Gold
银 Silver
铜 Cuprum
铂金 Platinum
钯金 Palladium
珠宝相关词句
jewellery n. [总称]珠宝,珠宝饰物
jewel n. ①宝石②宝石珠物贵重饰物
necklace n. 项圈
chain n. 链条项圈表链
earring n. 耳环,耳饰
discount n. vt. 折扣,打去(若干)折扣
bracelet n. 手镯
platinum n. 白金
carat n. 克拉(宝石的重量单位等于二百毫克)
messenger n. 送信者使者
brooch n. 胸针,饰针
ruby n. 红宝石
Would you like jewellery?
您要不要首饰?
Today is Mother's Day and all the jewelleryis on sale atSunin's.
今天是母亲节,尚韵店的所有首饰全部折价出售。
Do you have gold jewels?
你们有黄金饰品吗?
Yes,we have 14K and 18K gold necklaces,chains and earrings.
有,我们有14K和18K的金项链、手链和耳环。
May I have a look?
我能看一下吗?
Sure. Here is a nice gold necklace.
当然可以。这里有一根很好的`金项链。
Its regular price is$56,and now you can have it witha twenty percent discount.
原价是56美元,现在可以让你打八折买下。
It's very elegant. I'll take it.
这项链非常精致。我买了。
I want to buy some jewellery.
我要买些首饰。
What kind of jewellery do you like to have?
你要哪种首饰呢?
I should like to look at some bracelets.
我想看看手镯。
Pure gold or carats?
纯金的还是K金的?
What\'s the price for this one?
这只手镯多少钱?
How about five hundred dollars?
500元怎么样?
I'm sorry we only sell at fixed prices.
很抱歉,我们店不还价。
I wish to buy a diamond ring,too.
我还想买只钻戒。
Is this one suitable for you?
这只适合你吗?
No,it seems too old fashioned to me.
不,我觉得似乎太老式了。
Let me try it on. Oh,it\'s too small for me,haven't you got any larger ones?
让我戴戴看,呵,太小了。有稍大点儿的吗?
This fits me well,how much do you charge for it?
这只很合适,多少钱?
Is that a real string of pearls?
那串珍珠是真的吗?
You may take it on my word,if you find out it is an imitationyou may return it to me.
请相信我的话,假如您发现是假的话可以拿来退还给我。