表示对象自己的属性使用this调用成员变量,解决变量与局部变量之间的冲突问题
代码如下(示例):
public class Person{
public String name;
public int age;
public double height;
public Person(String name,int a,double height){
name=name;
age=age;
height=height;
}
public void introduce(){
System.out.println("我叫"+name+",今年"+age+"岁");
}
}
代码如下(示例):
public static void main(String[] args){
Person person = new Person("张三",20,178.5);
person.introduce();
}
控制台运行结果:
我叫null,今年0岁
分析:为什么会出现这种情况呢?当我们调用构造方法所传递的三个参数值“张三”、20和178.5最终并没有赋值到对象的三个属性中。那么,既然参数值没有被赋值到对象中,他们去了哪里呢?当构造方法的参数与类所定义的属性同名,根据“同名情况下,局部变量的优先级更高”原则,在构造方法执行的过程中,虚拟机会把参数值赋给参数本身,而不是赋值给对象的属性!具体来说,就是我们给构造方法的name参数传递法的值是“张三”最终没有被赋值到对象的name属性中,才导致introduce方法中打印出的name属性是null。当然,age和height这两个参数也是同样的赋值效果。
为了能够让虚拟机明白我们所期望的是:把“张三”这个字符串赋值给对象的name属性中,而不是“再一次”把它赋值给构造方法的参数,就需要把构造方法中的赋值语句作出如下修改:
public Person(String name,int age,double height){
this.name=name;
this.age=age;
this.height=height;
}
运行测试,控制台结果如下:
我叫张三,今年20岁
表示本对象自己的方法
我们给Person类增加了一个“打招呼”的方法叫做greet。在introduce方法当中,就可以通过“this。方法名”的方式来调用这个方法,表示调用的是“本对象自己的greet方法”。这是this关键字的第二种方法。当然,在introduce方法中并没有出现其他对象,所以方法名前面的this关键字也可以省略不写。
public void greet(){
System.out.println("hello,大家好");
}
public void introduce(){
this.greet();
System.out.println("我叫"+name+",今年"+age+"岁");
}
测试程序,结果如下:
hello,大家好
我叫张三,今年20岁
除此之外this关键字还有一种很重要的方法,那就是在this关键字的后面加上小括号,这样就表示调用了某个类自身的构造方法,我们修改一下Person类:
//构造方法1
public Person(String name,int age,double height){
this(name,age);//调用构造方法2
this.height=height;
}
//构造方法2
public Person(String name,int age){
this.name=name;
this.age=age;
}
在构造方法1中,通过“this(参数);”的方式调用了构造方法2.这就是this关键字的有一种用法。那么为什么要通过这种方式来调用构造方法呢?难道不能直接写一个“Person(name,age);”来调用吗?在java语言中,一个类的构造方法与类名相同。但是一个类当中也可以定义一个与类名相同的普通方法,换句话说:并不是只有构造方法与类名相同,普通方法也可以取和类名相同的名称(不过没人会这么干)。那么,在这种情况下,编译器如何区分这个方法是普通方法还是构造方法呢?很简单,普通方法的名称前面必须定义返回值类型,而构造方法的前面没有返回值类型的定义。这样,编译器就能够分清那个是构造方法,哪个是和类名相同的普通方法。
定义分的清,但是在调用的时候,都是通过方法名来调用的,这是该如何分的清代码中哪一句调用的是构造方法,哪一句调用的是普通方法呢?为了解决这个问题,JAVA语言规定,在本类中调用构造方法的时候,需要通过“this(参数)”的方法来调用。除此之外,Java语言还规定了这种调用方式所必须遵循的规则。首先,这种“this(参数)”方式只能在“其他构造方法中使用”,不能在普通方法中使用。如果在普通方法中使用,将会被视为语法错误,如下代码:
public void greet(){
this("张三",20);//此处代码错误,不能再普通方法中调用
Systen.out.println("hello,大家好");
}
其次,在一个构造方法中,用“this(参数)”的形式调用构造方法,"this(参数)”必须写在主调方法的第一行。第三,不能出现相互循环调用,也就是说,不能在构造方法1中调用方法2,有同时在构造方法2中调用方法1,如下:
//构造方法1
public Person(String name,int age,double height){
this(name,age);//在构造方法1中调用构造方法2
this.height=height;
}
//构造方法2
public Person(String name,int age){
this(name,agem,178.5);//在构造方法2中调用构造方法1
}
this关键字在我们编写内部类代码的时候,还有一种用途,那就是区分属性或方法的具体归属
代码如下(示例):
public class Outter{
public int a=0;//外部类的属性
class Inner{
public void printA(){
System.out.ptintln(a);//内部类方法调用外部类的属性
}
}
}
测试代码:
public static void main(String[] args){
//先创建外部类
Outter outter = new Outter();
//在创建外部类的内部类
Outter.Intter inner = outter.new Inner();
inner.printA();
}
运行结果:
0
//表示内部类方法调用外部类的属性
分析:在这段代码中,定义了外部类Outter,Outter有一个属性a,并且Outter中又定义了内部类,在内部类的print()方法中调用了外部类的a属性。我们都知道,一个内部类可以直接访问它所在外部类的属性和方法。这个特性在我们的上面这段代码中得到了体现。但是,如果内部类中出现了与外部类同名的属性或者方法时,该如何区分调用的到底是哪个属性或方法呢?比如说,在Inner类中也出现了a属性,那么输出语句中的a到底是指哪个a呢?其实很简单,如果输出语句中直接写a,那么调用的是内部类的a属性。为了强调它是内部类的a属性,我们也可以在a的前面加this关键字。如果我们希望调用的是外部类的a属性,可以用“外部类名.this.a”的方式来调用。
代码示例:
public class Outter{
public inbt a=0;//外部类的属性
class Inner{
public int a=10;//内部类的属性
public void printA(){
System.out.ptintln(a);//调用内部类的a属性,输出10
System.out.println(this.a);//调用内部类的a属性,输出10
System.out.println(Outter.this.a);//调用外部类的a属性,输出0
}
}
}
注意:
因为this是在对象内部指代自身的引用,所以this只能调用实例变量、实例方法和构造方法,不能调用类变量和类方法,也不能调用局部变量。
我正在尝试学习Ruby词法分析器和解析器(whitequarkparser)以了解更多有关从Ruby脚本进一步生成机器代码的过程。在解析以下Ruby代码字符串时。defadd(a,b)returna+bendputsadd1,2它导致以下S表达式符号。s(:begin,s(:def,:add,s(:args,s(:arg,:a),s(:arg,:b)),s(:return,s(:send,s(:lvar,:a),:+,s(:lvar,:b)))),s(:send,nil,:puts,s(:send,nil,:add,s(:int,1),s(:int,3))))任何人都可以向我解释生成的
在Ruby(尤其是Rails)中,您经常需要检查某物是否存在,然后对其执行操作,例如:if@objects.any?puts"Wehavetheseobjects:"@objects.each{|o|puts"hello:#{o}"end这是最短的,一切都很好,但是如果你有@objects.some_association.something.hit_database.process而不是@objects呢?我将不得不在if表达式中重复两次,如果我不知道实现细节并且方法调用很昂贵怎么办?显而易见的选择是创建一个变量,然后测试它,然后处理它,但是你必须想出一个变量名(呃),它也会在内存中
在尝试实现应用auto_orient的过程之后!对于我的图片,我收到此错误:ArgumentError(noimagesinthisimagelist):app/uploaders/image_uploader.rb:36:in`fix_exif_rotation'app/controllers/posts_controller.rb:12:in`create'Carrierwave在没有进程的情况下工作正常,但在添加进程后尝试上传图像时抛出错误。流程如下:process:fix_exif_rotationdeffix_exif_rotationmanipulate!do|image|
下面的代码工作正常:person={:a=>:A,:b=>:B,:c=>:C}berson={:a=>:A1,:b=>:B1,:c=>:C1}kerson=person.merge(berson)do|key,oldv,newv|ifkey==:aoldvelsifkey==:bnewvelsekeyendendputskerson.inspect但是如果我在“ifblock”中添加return,我会得到一个错误:person={:a=>:A,:b=>:B,:c=>:C}berson={:a=>:A1,:b=>:B1,:c=>:C1}kerson=person.merge(berson
我正在学习Ruby,遇到了inject。我正处于理解它的风口浪尖,但当我是那种需要真实世界的例子来学习一些东西的人时。我遇到的最常见的例子是人们使用inject来添加一个(1..10)范围的总和,我不太关心这个。这是一个任意的例子。在实际程序中我会用它做什么?我正在学习,所以我可以继续使用Rails,但我不必有一个以Web为中心的示例。我只需要一些我可以全神贯注的目标。谢谢大家。 最佳答案 inject有时可以通过它的“其他”名称reduce更好地理解。它是一个对Enumerable进行操作(迭代一次)并返回单个值的函数。它有许多有
我是Ruby和RubyonRails世界的新手。我已经阅读了一些指南,但我在使用以下语法时遇到了一些麻烦。我认为在Ruby中使用:condition语法来定义具有某种访问器的类属性,例如:classSampleattr_accessor:conditionend隐式声明“条件”属性的getter和setter。当我查看一些Rails示例代码时,我发现以下示例我并不完全理解。例如:@post=Post.find(params[:id])为什么它使用这种语法访问id属性,而不是:@post=Post.find(params[id])或者,例如:@posts=Post.find(:all):
我定义了一个方法:defmethod(one:1,two:2)[one,two]end当我这样调用它时:methodone:'one',three:'three'我得到:ArgumentError:unknownkeyword:three我不想从散列中一个一个地提取所需的键或排除额外的键。除了像这样定义方法之外,有没有办法规避这种行为:defmethod(one:1,two:2,**other)[one,two,other]end 最佳答案 如果不想写**other中的other,可以省略。defmethod(one:1,two:2
我在尝试使用Faraday将文件上传到网络服务时遇到问题。我的代码:conn=Faraday.new('http://myapi')do|f|f.request:multipartendpayload={:file=>Faraday::UploadIO.new('...','image/jpeg')}conn.post('/',payload)尝试发布后似乎没有任何反应。当我检查响应时this是我所看到的:#:post,:body=>#,#,@opts={}>,#],@index=0>>,#>],@ios=[#,#,@opts={}>,#],@index=0>,#],@index=0>
我使用raise(ConfigurationError.new(msg))引发错误我试着用rspec测试一下:expect{Base.configuration.username}.toraise_error(ConfigurationError,message)但这行不通。我该如何测试呢?目标是匹配message。 最佳答案 您可以使用正则表达式匹配错误消息:it{expect{Foo.bar}.toraise_error(NoMethodError,/private/)}这将检查NoMethodError是否由privateme
目录ChatGPT简介技术原理应用未来发展ChatGPT的10 种用法ChatGPT简介ChatGPT是一种基于深度学习的大型语言模型,由OpenAI公司开发。技术原理GPT是GenerativePre-trainedTransformer的缩写,意为生成式预训练变压器。它的技术原理是使用了一个基于注意力机制的变压器(Trans