WaterJim's Blog
快乐生活,尽情游戏
-
-
Java反射基础
Java反射的概念
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。有不少Java Web便是利用反射机制实现了强大功能,如Spring。
Java反射机制主要提供下面几种用途:
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的方法
- 在运行时修改变量的应用对象
- 实现动态代理
反射涉及的主要的类与作用
Class类与java.lang.reflect类库一起对反射的概念进行了支持,该类库包含了Field,Method以及Constructor类(每个类都实现了Methods)。这些类型的对象是由JVM在运行时创建的,用以表示未知类里面的对应的成员。这样,匿名对象的类信息就能在运行时被完全确定下来,而在编译时不需要知道任何事情。下面主要介绍下涉及到反射的主要的类与接口。
- Class:它表示正在运行的Java应用程序中的类和接口
- Field:提供有关类或接口的属性信息,以及对它的动态访问权限
- Constructor:提供关于类的单个构造方法的信息以及对它的访问权限
- Method:提供关于类或接口中某个方法信息
反射实例
因为可能涉及到一些相关的重复示例代码,这里就先行给出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29public class ReflectSample {
private int field1;
private int field2;
private String field3;
public ReflectSample() {
field1 = 1;
field2 = 2;
field3 = "before change";
}
public ReflectSample(int arg1, int arg2) {
this();
}
public void method1() {
}
public void method2(int arg) {
}
public void show(){
System.out.println("Reflect show method...");
}
}使用java的反射机制,一般需要遵循三步:
1.获得你想操作类的Class对象
2.通过第一步获得的Class对象去取得操作类的方法或是属性名
3.操作第二步取得的方法或是属性Java运行的时候,某个类无论生成多少个对象,他们都会对应同一个Class对象,它表示正在运行程序中的类和接口。如何取得操作类的Class对象,常用的有三种方式:
1.调用Class的静态方法forName,如上例;
2.使用类的.class语法,如:Class<?> cls = String.class;
3.调用对象的getClass方法,如:String str = “abc”;Class<?> cls = str .getClass();Constructor类相关实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.waterjim.example;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
public class ConstructorSample {
public static void main(String[] args) {
try {
Class reflectClass = Class.forName("com.waterjim.example.ReflectSample");
Constructor[] constructors = reflectClass.getConstructors();
for (int index = 0; index < constructors.length; index++) {
//构造函数的名字
System.out.println("Constructor " + index + " : " + constructors[index].getName());
//构造函数的访问权限
System.out.println("Constructor Modifier : " + Modifier.toString(constructors[index].getModifiers()));
// 获取构造方法中的参数
Class[] paramTypes = constructors[index].getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
if (i > 0) {
System.out.print(",");
}
if (paramTypes[i].isArray()) {
System.out.println(paramTypes[i].getComponentType().getName() + "[]");
} else {
System.out.print(paramTypes[i].getName());
}
}
System.out.println();
System.out.println("---------------------------------------------------");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}Field类相关实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56package com.waterjim.example;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class FieldSample {
public static void main(String[] args) {
try {
Class reflectClass = Class.forName("com.waterjim.example.ReflectSample");
Field[] fields = reflectClass.getDeclaredFields();
for(Field field : fields){
//变量的名称
System.out.println("Field name : " + field.getName());
//变量的访问权限
System.out.println("Field Modifier : " + Modifier.toString(field.getModifiers())) ;
//变量的类型
System.out.println("Field type : " + field.getType().getName());
System.out.println("---------------------------------------------------------");
System.out.println();
}
System.out.println("Field change------------------------");
//获取私有变量,并改变他的值
//实例化一个对象
ReflectSample reflectSample = (ReflectSample) reflectClass.newInstance();
//获取私有变量对应的Field对象
Field privateField = reflectClass.getDeclaredField("field3");
privateField.setAccessible(true);
System.out.println("Before : " + privateField.get(reflectSample));
//改变其指向的对象引用
privateField.set(reflectSample, new String("after change..."));
System.out.println("Before : " + privateField.get(reflectSample));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}Method类相关实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66package com.waterjim.example;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class MethodSample {
public static void main(String[] args) {
try {
Class reflectClass = Class.forName("com.waterjim.example.ReflectSample");
// 获取指定类的所有方法
// 注意:这里使用的是 getDeclaredMethods(), 还有一个 getMethods(),
// 但是后者不能获取声明为private的方法
Method[] methods = reflectClass.getDeclaredMethods();
for (Method method : methods) {
System.out.println("Method name : " + method.getName());
System.out.println("Method modifier : " + Modifier.toString(method.getModifiers()));
// 获取构造方法中的参数
Class[] paramTypes = method.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
if (i > 0) {
System.out.print(",");
}
if (paramTypes[i].isArray()) {
System.out.println(paramTypes[i].getComponentType().getName() + "[]");
} else {
System.out.print(paramTypes[i].getName());
}
}
System.out.println();
System.out.println("---------------------------------------------------");
}
System.out.println("Use Method.invoke-----------------------------------");
//实例化一个对象
ReflectSample reflectSample = (ReflectSample) reflectClass.newInstance();
//获取show()对应的Method对象,注意这里使用的是getDeclaredMethod();
Method showMethod = reflectClass.getDeclaredMethod("show");
//如果操作的方法是一个私有方法,需要先设置其为可访问
showMethod.setAccessible(true);
//调用show()方法
showMethod.invoke(reflectSample);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
-
Android工程常用代码段汇聚(持续更新)
隐藏状态栏及虚拟键
1
2
3
4
5
6
7if (Build.VERSION.SDK_INT < 14) return;
mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); -
Android工程常见错误汇聚(持续更新)
-
Android Activity启动流程
-
Hexo新博文发布操作
导语
关于Hexo
Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 Markdown(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页。
Hexo的安装及配置
安装前提
安装 Hexo 相当简单。然而在安装前,您必须检查电脑中是否已安装下列应用程序:
Node.js
Git如果您的电脑中已经安装上述必备程序,那么恭喜您!接下来只需要使用 npm 即可完成 Hexo 的安装。
1
$ npm install -g hexo-cli
所有必备的应用程序安装完成后,即可使用 npm 安装 Hexo。
安装 Hexo 完成后,请执行下列命令,Hexo 将会在指定文件夹中新建所需要的文件。1
2
3$ hexo init <folder>
$ cd <folder>
$ npm install新建完成后,指定文件夹的目录如下:
1
2
3
4
5
6
7
8.
├── _config.yml
├── package.json
├── scaffolds
├── source
| ├── _drafts
| └── _posts
└── themes否则,请先安装上述应用程序,这里不再细述。
其他介绍,请到官方网站
Git及相关操作
安装Git客户端
Windows:下载并安装 git.
Mac:使用 [Homebrew], [MacPorts] 或[下载] 安装程序 安装。
Linux (Ubuntu, Debian):sudo apt-get install git-core
Linux (Fedora, Red Hat, CentOS):sudo yum install git-core生成密钥,并配置到Github
检查SSH keys的设置
首先我们需要检查你电脑上现有的ssh key:
1
$ cd ~/. ssh 检查本机的ssh密钥
如果提示:No such file or directory 说明你是第一次使用git。
生成新的SSH Key:
1
2
3
4
5
6$ ssh-keygen -t rsa -C "邮件地址@youremail.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/your_user_directory/.ssh/id_rsa):<回车>
Enter passphrase (empty for no passphrase):<输入加密串>
Enter same passphrase again:<再次输入加密串>在回车中会提示你输入一个密码,这个密码会在你提交项目时使用,如果为空的话提交项目时则不用输入。这个设置是防止别人往你的项目里提交内容。
添加SSH Key到GitHub
在本机设置SSH Key之后,需要添加到GitHub上,以完成SSH链接的设置。
- 打开本地C:\Documents and Settings\Administrator.ssh\id_rsa.pub文件。此文件里面内容为刚才生成人密钥。如果看不到这个文件,你需要设置显示隐藏文件。准确的复制这个文件的内容,才能保证设置的成功。
- 登陆github系统。点击右上角的 Account Settings—->SSH Public keys —-> add another public keys
- 把你本地生成的密钥复制到里面(key文本框中), 点击 add key 就ok了
若有问题,请参考Generating an SSH key
测试
可以输入下面的命令,看看设置是否成功,git@github.com的部分不要修改:
1
$ ssh -T git@github.com
Github上的其他设置
创建仓库,并设置主页
登录后系统,在github首页,点击页面右下角「New Repository」;
填写项目信息:
project name:waterjim.github.io
description: 仓库描述注:Github Pages的Repository名字是特定的,比如我的Github账号为waterjim,那么我Github Pages Repository名字就是waterjim.github.io
点击「Create Repository」 完成创建。
创建新博文及提交
使用以下命令创建新的博文
1
$ hexo new "新博文标题"
然后使用Markdown编辑器进行博文编写。同时在发布之前,需要进行一下操作:
安装deploy1
$ npm install hexo-deployer-git --save
需要对Hexo配置文件进行一些配置:
1
2
3
4deploy:
type: git
repo: git@github.com:WaterJim/waterjim.github.io.git
branch: master执行一下命令(Window平台需要使用Git Bash执行下面命令)
1
2
3$ hexo clean
$ hexo g
$ hexo d这时候可以访问你的网站是否已经发布成功。如我的博客:http://waterjim.github.io/
其他
Markdown相关介绍
Markdown语法入门:http://www.jianshu.com/p/1e402922ee32/
Markdown编辑器:http://www.williamlong.info/archives/4319.html
-
Eclipse中的subclipse(SVN)
Subclipse介绍
正如Win端的TortoiseSVN一样,Subclipse是Eclipse上最常用的提供SVN版本控制管理插件。使用该插件便可以对项目版本控制库进行相应的操作,如代码更新,提交,版本回退以及分支创建与合并,建立项目里程碑等等操作。下面是一段官方关于Subclipse的介绍:
An Eclipse Team Provider plug-in providing support for Subversion within the Eclipse IDE. Developed and maintained by Subversion core committers, Subclipse is always in synch with the latest Subversion features and releases.
Subclipse includes the CollabNet Merge Client originally developed as part of the CollabNet Desktop - Eclipse Edition. The CollabNet Merge Client provides powerful graphical merge capabilities that leverages the merge tracking functionality that was added as part of the Subversion 1.5 release.
Subclipse includes an optional Mylyn connector that enables Mylyn to create automatic changesets based on the tasks you are working on. It also enables links to tasks when viewing history of Subversion commits.
Finally, Subclipse includes a powerful revision graph feature that is built with Eclipse GEF/Draw2D. This allows you to visualize commits and merges across Subversion branches.
在Eclipse中安装SVN插件
检查你的Eclipse是否已经安装了Subclipse
打开Eclipse,选择Help——->Install New Sorfware———–>右下的”already installed?”
打开页面后,会显示你的Eclipse当前已经安装的插件,查看是否有SVN相关的插件存在。
在Eclipse中安装Subclipse
打开Eclipse,选择Help——->Eclipse Markplace,搜索”subclipse”
根据提示安装完成后重启即可。(有弹窗提示的只要选择确认即可)
常规用法
显示版本资源库窗口,添加远程版本库
Window ————> Show View ————> Other ————-> SVN添加文件,并且提交到版本库当中
右键Project ————–> Team —————–>提交
删除文件
解决代码冲突
右键发生冲突的文件————> 编辑冲突
修改好冲突后右键冲突文件————> 标记解决
主线与分支管理
常见SVN仓库目录介绍
1.–Trunka
SVN组成Trunka,Trunk是放置稳定代码的主要环境,就好像一个汽车工厂,负责将成品的汽车零件组装在一起。
除非你必须处理一些容易且能迅速解决的BUG,或者你必须添加一些无关逻辑的文件(比如媒体文件:图像,视频,CSS等等),否则永远不要在trunk直接做开发
不要因为特殊的需求而去对先前的版本做太大的改变,如何相关的情况都意味着需要建立一个branch(如下所述)
不要提交一些可能破坏trunk的内容,例如从branch合并。
2.–Branches
SVN组成branches,一个branch就是从一个SVN仓库中的子树所作的一份普通拷贝。通常情况它的工作类似与UNIX系统上的符号链接,但是你一旦在一个SVNbranch里修改了一些文件,并且这些被修改的文件从拷贝过来的源文件独立发展,就不能这么认为了。当一个branch完成了,并且认为它足够稳定的时候,它必须合并回它原来的拷贝的地方,也就是说:如果原来是从trunk中拷贝的,就应该回到trunk去,或者合并回它原来拷贝的父级branch。
如果你需要修改你的应用程序,或者为它开发一个新的特性,请从trunk中创建一个新的branch,然后基于这个新的分支进行开发
除非是因为必须从一个branch中创建一个新的子branch,否则新的branch必须从trunk创建
当你创建了一个新branch,你应当立即切换过去。如果你没有这么做,那你为什么要在最初的地方创建这个分支呢?
3.–Tags
SVN组成Tags。从表面上看,SVNbranches和SVNtags没有什么差别,但是从概念上来说,它们有许多差别。其实一个SVNtags就是项目的里程碑。创建分支,切换到分支
有些时候,根据业务需要,我们需要从项目主干上创建独立的分支。
比如项目demo下有两个小组,svn下有一个trunk版。由于客户需求突然变化,导致项目需要做较大改动,此时项目组决定由小组1继续完成原来正进行到一半的工作(某个模块),小组2进行新需求的开发。那么此时,我们就可以为小组2建立一个分支,分支其实就是trunk版(主干线)的一个copy版,不过分支也是具有版本控制功能的,而且是和主干线相互独立的,当然,到最后我们可以通过[合并]功能,将分支合并到trunk上来,从而最后合并为一个项目。将主干代码合并到分支
当我们在branch中完成了业务需求功能开发,在将分支代码合并到主干之前,需要将主干代码合并到当前分支,以防主干版本与该分支初期版本相差太远。
操作如下:
切换到当前分支——->Team——>合并这里的来源选择主干
将分支代码合并到主干
操作如下:
切换到当前主干——>Team——>合并这里的来源选择想要合并的支线。
注意上面的版本号选择刚从主线拉出该分支的版本号;
下面的版本号一般选择最新版本。
工作流样例
假设你必须添加了一个特性至一个项目,且这个项目是受版本控制的,你差不多需要完成如下几个步骤:
1.使用SVNcheckout或者SVNswitch从这个项目的trunk获得一个新的工作拷贝(branch)
2.使用SVN切换至新的branch
3.完成新特性的开发(当然,要做足够的测试,包括在开始编码前)
4.一旦这个特性完成并且稳定(已提交),并经过你的同事们确认,切换至trunk
5.合并你的分支至你的工作拷贝(trunk),并且解决一系列的冲突
6.重新检查合并后的代码
7.如果可能的话,麻烦你的同事对你所编写、更改的代码进行一次复查(review)
8.提交合并后的工作拷贝至trunk -
SVN远程服务器搭建(基于Ubuntu)
-
'Git远程仓库创建'
-
Hello World
Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.
Quick Start
Create a new post
1
$ hexo new "My New Post"
More info: Writing
Run server
1
$ hexo server
More info: Server
Generate static files
1
$ hexo generate
More info: Generating
Deploy to remote sites
1
$ hexo deploy
More info: Deployment