smali语言详解之一般/构造方法(函数)的声明与返回值关键字
一、 smali语言的方法声明格式
.method
与.end method
成对出现,类似于java中的花括号
1.1、非静态的一般方法
.method 权限修饰关键字 方法名(参数类型)返回值类型
#方法内容
.end method
1.2、静态的一般方法
.method 权限修饰关键字 static 方法名(参数类型)返回值类型
#方法内容
.end method
1.3、构造方法
.method 权限修饰关键字 constructor <init>(参数类型)返回值类型
#方法内容
.end method
二、示例
2.1、空参且返回值为空的方法示例
以下为java全部代码
package com.ylw.helloworld;
public class Test {
public static void getName(){
}
}
对应的smali全部代码如下
.class public Lcom/ylw/helloworld/Test;#(此行不可删)Lcom/ylw/helloworld/Test;为类的全包名路径,根据实际情况有所不同
.super Ljava/lang/Object;#(此行不可删)声明父类,当没有使用extends写明继承时,默认继承Object类
.source "Test.java"#(此行可删)#表示此smali代码对应的java源码文件
# direct methods#自动生成的无参构造
.method public constructor <init>()V
.registers 1
.prologue
.line 3
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method#与.method成对出现,表示方法的结束
.method public static getName()V#最后的V表示返回值为void,非静态不写static即可
.registers 0
.prologue
.line 7
return-void#与返回值为V相对应
.end method#与.method成对出现,表示方法的结束
2.2、有参且返回值为空的方法示例
2.2.1、概览对比
java全部代码如下
package com.ylw.helloworld;
public class Test {
public static void getNameA(int a){
}
public static void getNameB(int a,String b){
}
public static void getNameC(String b,int a){
}
public static void getNameD(String b,int a,String[] args){
}
}
为了便于对比,以下只展示和java代码中四个方法对应的smali代码
.method public static getNameA(I)V
.registers 1
.param p0, "a" # I
.prologue
.line 7
return-void
.end method
.method public static getNameB(ILjava/lang/String;)V
.registers 2
.param p0, "a" # I
.param p1, "b" # Ljava/lang/String;
.prologue
.line 11
return-void
.end method
.method public static getNameC(Ljava/lang/String;I)V
.registers 2
.param p0, "b" # Ljava/lang/String;
.param p1, "a" # I
.prologue
.line 15
return-void
.end method
.method public static getNameD(Ljava/lang/String;I[Ljava/lang/String;)V
.registers 3
.param p0, "b" # Ljava/lang/String;
.param p1, "a" # I
.param p2, "args" # [Ljava/lang/String;
.prologue
.line 19
return-void
.end method
2.2.2、单参且返回值为空的方法详解
java代码如下
public static void getNameA(int a){
}
对应的smali代码如下
.method public static getNameA(I)V#括号里的大写I代表参数类型为int,结尾V代表返回值为void
.registers 1
.param p0, "a" # I#(此行可不写)此行代表第一个参数p0在原java代码里的名称是a,后面自动生成的注释提示参数类型为int
.prologue
.line 7
return-void#返回值为空与void对应
.end method
2.2.2、多参且返回值为空的方法详解
java代码如下
public static void getNameB(int a,String b){
}
对应的smali代码如下,注意当有多个参数时,smali语言中无需用符号分隔参数,直接顺着写即可,getNameB(ILjava/lang/String;)括号内第一个字母I表示第一个参数类型为int,第二串全包名路径Ljava/lang/String;表示第二个参数类型为String,因为java中String为类而不是基本数据类型,所以要写全包名路径
.method public static getNameB(ILjava/lang/String;)V#注意当有多个参数时,smali语言中无需用符号分隔参数,直接顺着写即可
.registers 2
.param p0, "a" # I#(此行可不写)此行代表第一个参数p0在原java代码里的名称是a,后面自动生成的注释提示参数类型为int
.param p1, "b" # Ljava/lang/String;#(此行可不写)此行代表第一个参数p0在原java代码里的名称是b,后面自动生成的注释提示参数类型为String
.prologue
.line 11
return-void#返回值为空与void对应
.end method
2.3、返回值非空的方法示例
2.3.1、方法返回关键字介绍
方法返回关键字主要有以下四种
return-void
返回值为空时使用return-object
返回值为类对象时使用,如java中的字符串String和数组类型return
返回值为非64位基本数据类型时使用,如int、float、boolean,为long、double时除外,因为long、double为64位数据类型return-wide
返回值为64位数据类型时使用,如long、double
方法返回关键与对应的数据类型关系表如下
smali方法返回关键字 | 对应java的数据类型 |
---|---|
return | byte |
return | short |
return | int |
return-wide | long(64位) |
return | float |
return-wide | double(64位) |
return | char |
return | boolean |
return-void | void |
return-object | 数组 |
return-object | Object、String字符串、自己定义的类对象 |
2.3.2、方法返回值非空示例和详解
java代码如下,返回值为字符串hello
public static String getNameA(int a){
return "hello";
}
对应的smali代码如下,使用关键字return-object进行String类型的返回
.method public static getNameA(I)Ljava/lang/String;
.registers 2
.param p0, "a" # I
.prologue
.line 6
const-string v0, "hello"#定义字符串常量hello放到v0中
return-object v0#返回v0,v0中存放的是String类型的hello,所以使用关键字return-object
.end method
2.4、构造方法示例
java完整代码如下,java中不显式写出构造方法时会默认加上
package com.ylw.helloworld;
public class Test {
}
对应的完整smali代码如下
.class public Lcom/ylw/helloworld/Test;#(此行不可删)Lcom/ylw/helloworld/Test;为类的全包名路径,根据实际情况有所不同
.super Ljava/lang/Object;#(此行不可删)声明父类,当没有使用extends写明继承时,默认继承Object类
.source "Test.java"#(此行可删)#表示此smali代码对应的java源码文件
# direct methods#自动生成的注释
.method public constructor <init>()V#无参构造,V表示返回值为void
.registers 1
.prologue
.line 3
invoke-direct {p0}, Ljava/lang/Object;-><init>()V#调用父类Object类的构造方法,invoke为方法调用关键字,此处不详细介绍
return-void#对应返回值为空
.end method#方法结束标识