导航:首页 > 编程语言 > java传地址

java传地址

发布时间:2022-07-06 03:38:43

java中有地址参数传递吗

你需要明白,地址参数传递的真实含义,然后就明白了,只拿概念去套是没有意义的。套概念只会今天问 java 有没有,明天问其它的语言有没有。

java 的参数传递不同于按值传递,也不完全同于按地址传递,因为这需要区分基本类型和抽象类型。
名义上 Java 都是按值传递,但对于抽象类型来说又有引用传递的效果。指向原始对象,函数调用后的效果也导致了目标对象被改动,之后持有指向目标对象的符号的变量就跟着有了变化,这点就像引用传递。

所以 Java 的核心人士都说 Java 只有按值传递。但理解了 Java 的引用之后就明白,对于抽象类型的对象,这其实也是引用传递。所以在 Java 中没直接与 C++ 地址传递。

Java API 中有些类型的是 immutable,就是说它的状态在创建之后不再更改,所以修改需要创建一个全新的对象,比如 String, Integer 之类的,所以 str + "sest" 其实并未改变 str 对象本身,所以需要用 str = str + "test" 来接收改变之后的结果,它是一个新的 String 对象,不同于 str + "test" 调用之前的那个 str。

㈡ java值传递和地址传递

JAVA传递参数有两种方式:值传递和引用传递
值传递是传递数据:如基本数据类型都是值传递
引用传递是把形参和实参的指针指向了堆中的同一对象,对象的引用和数组的引用。

实参,Java的基本数据类型,如int,double等在函数的参数传递时,传递的是副本。String也属于这一范畴。

形参,而如果是对象,则传递的是引用。

如下代码实例:

{

@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
personp=newperson();
p.name="ken";
p.age="12";

reset(p);//传递的是p的指针地址,方法里面在对p的属性进行修改,方法结束后影响依然存在。

Stringname=p.name;
Stringage=p.age;
System.out.println(name+age);
//name=gg,age=223
setContentView(R.layout.main);
}

privatevoidreset(personap){
ap.name="gg";
ap.age="223";
} classperson{
Stringname;
Stringage;
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicStringgetAge(){
returnage;
}
publicvoidsetAge(Stringage){
this.age=age;
}
}

㈢ java传地址

a的地址赋值给b变量,就是b指向的值是a原来指向的值

java好像只有传值和传引用,好像没有传地址

㈣ JAVA数组地址传递问题!

在Java中,参数的传递严格意义上讲都是传值的,只不过简单很容易分清楚。而对于对象,有些复杂。

首先,在Java中是先声明一个类的变量。然后,用类生成一个类的实例,也就是在内存中的类的实例区域,最后把这个区域的指针赋给类的这个变量。注意,变量中存的是指向对象的指针。

若是按传址传参数,是要改变这个对象变量所指的内存对象区域,也就是要在方法内把新对象赋给方法外的对象变量。但是,这在Java中办不到。因为Java是把对象变量中的对象指针传入方法,并没有把变量本身的地址传入方法;在方法中,会生成新变量接受这个对象的指针。所以,在Java方法中,可以改变当前对象中的内容,却不能改变方法外边变量的值,即所指向的对象。对于传值、传址的分析就是为了在应用中少犯错误。其他是次要的。

明白没有,是传值而不是传值的地址!地址没有变,C当然不变了!

㈤ java 传值、传址问题

以前我看过的文章,推荐给你:

JAVA的参数传递,基本类型是把实参赋给形参, 对象是COPY一个副本堆栈里.

很多Java程序员只求追随新生的事物,却连基本的概念都没有,很明显是基本功不过硬,讨论Java的基本功,下面便是在这个想法下催生出的第一篇文章。

Java基本功——Reference

有这样一种说法,如今争锋于IT战场的两大势力,MS一族偏重于底层实现,Java一族偏重于系统架构。说法根据无从考证,但从两大势力各自的社区力量和图书市场已有佳作不难看出,此说法不虚。于是,事情的另一面让人忽略了。
偏巧,我是一个喜欢探究底层实现的Java程序员,虽然我的喜好并非纯正咖啡,剑走偏锋却别是一番风味。

Reference
Java世界泰山北斗级大作《Thinking In Java》切入Java就提出“Everything is Object”。在Java这个充满Object的世界中,reference是一切谜题的根源,所有的故事都是从这里开始的。

Reference是什么?
如果你和我一样在进入Java世界之前曾经浪迹于C/C++世界,就一定不会对指针陌生。谈到指针,往日种种不堪回首的经历一下子涌上心头,这里不是抱怨的地方,让我们暂时忘记指针的痛苦,回忆一下最初接触指针的甜蜜吧!还记得你看过的教科书中,如何讲解指针吗?留在我印象中的一种说法是,指针就是地址,如同门牌号码一样,有了地址,你可以轻而易举找到一个人家,而不必费尽心力的大海捞针。
C++登上历史舞台,reference也随之而来,容我问个小问题,指针和reference区别何在?我的答案来自于在C++世界享誉盛名的《More Effective C++》。

没有null reference。
reference必须有初值。
使用reference要比使用指针效率高。因为reference不需要测试其有效性。
指针可以重新赋值,而reference总是指向它最初获得的对象
设计选择:
当你指向你需要指向的某个东西,而且绝不会改指向其它东西,或是当你实作一个运算符而其语法需要无法有指针达成,你就应该选择reference。其它任何时候,请采用指针。

这和Java有什么关系?
初学Java,鉴于reference的名称,我毫不犹豫的将它和C++中的reference等同起来。不过,我错了。在Java中,reference可以随心所欲的赋值置空,对比一下上面列出的差异,就不难发现,Java的reference如果要与C/C++对应,它不过是一个穿着reference外衣的指针而已。
于是,所有关于C中关于指针的理解方式,可以照搬到Java中,简而言之,reference就是一个地址。我们可以把它想象成一个把手,抓住它,就抓住了我们想要操纵的数据。如同掌握C的关键在于掌握指针,探索Java的钥匙就是reference。

一段小程序
我知道,太多的文字总是令人犯困,那就来段代码吧!
public class ReferenceTricks {
public static void main(String[] args) {
ReferenceTricks r = new ReferenceTricks();
// reset integer
r.i = 0;
System.out.println("Before changeInteger:" + r.i);
changeInteger(r);
System.out.println("After changeInteger:" + r.i);

// just for format
System.out.println();

// reset integer
r.i = 0;
System.out.println("Before changeReference:" + r.i);
changeReference(r);
System.out.println("After changeReference:" + r.i);
}

private static void changeReference(ReferenceTricks r) {
r = new ReferenceTricks();
r.i = 5;
System.out.println("In changeReference: " + r.i);
}

private static void changeInteger(ReferenceTricks r) {
r.i = 5;
System.out.println("In changeInteger:" + r.i);
}

public int i;
}

对不起,我知道,把一个字段设成public是一种不好的编码习惯,这里只是为了说明问题。
如果你有兴趣自己运行一下这个程序,我等你!

OK,你已经运行过了吗?结果如何?是否如你预期?下面是我在自己的机器上运行的结果:
Before changeInteger:0
In changeInteger:5
After changeInteger:5

Before changeReference:0
In changeReference: 5
After changeReference:0
这里,我们关注的是两个change——changeReference和changeInteger。从输出的内容中,我们可以看出,两个方法在调用前和调用中完全一样,差异出现在调用后的结果。

糊涂的讲解
先让我们来分析一下changeInteger的行为。
前面说过了,Java中的reference就是一个地址,它指向了一个内存空间,这个空间存放着一个对象的相关信息。这里我们暂时不去关心这个内存具体如何排布,只要知道,通过地址,我们可以找到r这个对象的i字段,然后我们给它赋成5。既然这个字段的内容得到了修改,从函数中返回之后,它自然就是改动后的结果了,所以调用之后,r对象的i字段依然是5。下图展示了changeInteger调用前后内存变化。

Reference +--------+ Reference +--------+
---------->| i = 0 | ---------->| i = 5 |
|--------| |--------|
| Memory | | Memory |
| | | |
| | | |
+--------+ +--------+

调用changeInteger之前 调用changeInteger之后

让我们把目光转向changeReference。
从代码上,我们可以看出,同changeInteger之间的差别仅仅在于多了这么一句。
r = new ReferenceTricks();
这条语句的作用是分配一块新的内存,然后将r指向它。
执行完这条语句,r就不再是原来的r,但它依然是一个ReferenceTricks的对象,所以我们依然可以对这个r的i字段赋值。到此为止,一切都是那么自然。

Reference +--------+ +--------+
---------->| i = 0 | | i = 0 |
|--------| |--------|
| Memory | | Memory |
| | Reference |--------|
| | ---------->| i = 5 |
+--------+ +--------+

调用changeReference之前 调用changeReference之后

顺着这个思路继续下去的话,执行完changeReference,输出的r的i字段,那么应该是应该是新内存中的i,所以应该是5。至于那块被我们抛弃的内存,Java的GC功能自然会替我们善后的。
事与愿违。
实际的结果我们已经看到了,输出的是0。
肯定哪个地方错了,究竟是哪个地方呢?

参数传递的秘密
知道方法参数如何传递吗?
记得刚开始学编程那会儿,老师教导,所谓参数,有形式参数和实际参数之分,参数列表中写的那些东西都叫形式参数,在实际调用的时候,它们会被实际参数所替代。
编译程序不可能知道每次调用的实际参数都是什么,于是写编译器的高手就出个办法,让实际参数按照一定顺序放到一个大家都可以找得到的地方,以此作为方法调用的一种约定。所谓“没有规矩,不成方圆”,有了这个规矩,大家协作起来就容易多了。这个公共数据区,现在编译器的选择通常是“栈”,而所谓的顺序就是形式参数声明的顺序。
显然,程序运行的过程中,作为实际参数的变量可能遍布于内存的各个位置,而并不一定要老老实实的呆在栈里。为了守“规矩”,程序只好将变量复制一份到栈中,也就是通常所说的将参数压入栈中。
打起精神,谜底就要揭晓了。
我刚才说什么来着?将变量复制一份到栈中,没错,“复制”!
这就是所谓的值传递。
C语言的旷世经典《The C Programming Language》开篇的第一章中,谈到实际参数时说,“在C中,所有函数的实际参数都是传‘值’的”。
马上会有人站出来,“错了,还有传地址,比如以指针传递就是传地址”。
不错,传指针就是传地址。在把指针视为地址的时候,是否考虑过这样一个问题,它也是一个变量。前面的讨论中说过了,参数传递必须要把参数压入栈中,作为地址的指针也不例外。所以,必须把这个指针也复制一份。函数中对于指针操作实际上是对于这个指针副本的操作。
Java的reference等于C的指针。所以,在Java的方法调用中,reference也要复制一份压入堆栈。在方法中对reference的操作就是对这个reference副本的操作。
谜底揭晓
好,让我们回到最初的问题上。
在changeReference中对于reference的赋值实际上是对这个reference的副本进行赋值,而对于reference的本尊没有产生丝毫的影响。
回到调用点,本尊醒来,它并不知道自己睡去的这段时间内发生过什么,所以只好当作什么都没发生过一般。就这样,副本消失了,在方法中对它的修改也就烟消云散了。

也许你会问出这样的问题,“听了你的解释,我反而对changeInteger感到迷惑了,既然是对于副本的操作,为什么changeInteger可以运作正常?”
呵呵,很有趣的大脑短路现象。
好,那我就用前面的说法解释一下changeInteger的运作。
所谓复制,其结果必然是副本完全等同于本尊。reference复制的结果必然是两个reference指向同一块内存空间。
虽然在方法中对于副本的操作并不会影响到本尊,但对内存空间的修改确实实实在在的。
回到调用点,虽然本尊依然不知道曾经发生过的一切,但它按照原来的方式访问内存的时候,取到的确是经过方法修改之后的内容。
于是方法可以把自己的影响扩展到方法之外。

多说几句
这个问题起源于我对C/C++中同样问题的思考。同C/C++相比,在changeReference中对reference赋值可能并不会造成什么很严重的后果,而在C/C++中,这么做却会造成臭名昭着的“内存泄漏”,根本的原因在于Java拥有了可爱的GC功能。即便这样,我仍不推荐使用这种的手法,毕竟GC已经很忙了,我们怎么好意思再麻烦人家。
在C/C++中,这个问题还可以继续引申。既然在函数中对于指针直接赋值行不通,那么如何在函数中修改指针呢?答案很简单,指针的指针,也就是把原来的指针看作一个普通的数据,把一个指向它的指针传到函数中就可以了。
同样的问题到了Java中就没有那么美妙的解决方案了,因为Java中可没有reference的reference这样的语法。可能的变通就是将reference进行封装成类。至于值不值,公道自在人心。

参考文献
1 《Thinking in Java》
2 《More Effective C++》
3 《The C Programming Language》

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1376960

㈥ java中怎么让函数传地址

你好 java中没有地址传递
java中都是基于值的传递
基本类型变量作为参数传递的话,是直接把变量值复制过去
引用类型作为参数传递的话,是把引用里面的值复制过去

㈦ 请问:JAVA中对象作为参数,是按值传递,还是按地址传递

对象做参数,传过去的是地址。
所以你在你调用的方法里面可以修改对象的某些属性(值),基本数据类型就不可以。Java中数组也是传递地址的。
因此我们如果在某些地方调用其他方法时,需要用传进去的参数把结果带回来,就可以用对象或者数组做参数,但用基本数据类型,就不能把结果带回来

㈧ 如何用java程序实现上传文件到指定的URL地址

参考代码如下:
import java.io.*;
/**
* 复制文件夹或文件夹
*/
public class CopyDirectory {
// 源文件夹
static String url1 = "f:/photos";
// 目标文件夹
static String url2 = "d:/tempPhotos";
public static void main(String args[]) throws IOException {
// 创建目标文件夹
(new File(url2)).mkdirs();
// 获取源文件夹当前下的文件或目录
File[] file = (new File(url1)).listFiles();
for (int i = 0; i < file.length; i++) {
if (file[i].isFile()) {
// 复制文件
File(file[i],new File(url2+file[i].getName()));
}
if (file[i].isDirectory()) {
// 复制目录
String sourceDir=url1+File.separator+file[i].getName();
String targetDir=url2+File.separator+file[i].getName();
Directiory(sourceDir, targetDir);
}
}
}
// 复制文件
public static void File(File sourceFile,File targetFile)
throws IOException{
// 新建文件输入流并对它进行缓冲
FileInputStream input = new FileInputStream(sourceFile);
BufferedInputStream inBuff=new BufferedInputStream(input);

// 新建文件输出流并对它进行缓冲
FileOutputStream output = new FileOutputStream(targetFile);
BufferedOutputStream outBuff=new BufferedOutputStream(output);

// 缓冲数组
byte[] b = new byte[1024 * 5];
int len;
while ((len =inBuff.read(b)) != -1) {
outBuff.write(b, 0, len);
}
// 刷新此缓冲的输出流
outBuff.flush();

//关闭流
inBuff.close();
outBuff.close();
output.close();
input.close();
}
// 复制文件夹
public static void Directiory(String sourceDir, String targetDir)
throws IOException {
// 新建目标目录
(new File(targetDir)).mkdirs();
// 获取源文件夹当前下的文件或目录
File[] file = (new File(sourceDir)).listFiles();
for (int i = 0; i < file.length; i++) {
if (file[i].isFile()) {
// 源文件
File sourceFile=file[i];
// 目标文件
File targetFile=new
File(new File(targetDir).getAbsolutePath()
+File.separator+file[i].getName());
File(sourceFile,targetFile);
}
if (file[i].isDirectory()) {
// 准备复制的源文件夹
String dir1=sourceDir + "/" + file[i].getName();
// 准备复制的目标文件夹
String dir2=targetDir + "/"+ file[i].getName();
Directiory(dir1, dir2);
}
}
}
}

㈨ java 里函数调用怎么传递地址

Java 里面不存在指针之类的运算```
也不存在想 C#里面的 ref 值引用
但可以用 JavaBean 里面的get 和 set 方法封装数据,也挺好用的

阅读全文

与java传地址相关的资料

热点内容
c开源cf源码 浏览:947
如何取消掉添加进app资源库 浏览:728
上海政务APP叫什么 浏览:812
黑马程序员一线薪资 浏览:109
滴滴app有青桔优惠券怎么用 浏览:123
删哪几个文件夹加速 浏览:28
创建电影源码爬取项目 浏览:453
java多余的空格 浏览:83
手机软件连接云服务器 浏览:888
内圆弧编程实例 浏览:48
饼干pdf 浏览:423
kylin源码大全 浏览:687
android构建工具 浏览:422
zigy命令行选项不兼容 浏览:561
加密系统能录屏吗 浏览:190
安卓淘宝点进去跳链接如何关闭 浏览:786
u盘加密了手机读取不了 浏览:947
oracle11g启动命令 浏览:931
怎么把视频传到自己的文件夹 浏览:700
福州电动车在哪个app上摇号 浏览:818