#is everything in Java a pointer ?
1 messages · Page 1 of 1 (latest)
<@&987246683568103514> please have a look, thanks.
Here is an AI assisted attempt to answer your question 🤖. Maybe it helps! In any case, a human is on the way 👍. To continue talking to the AI, you can use </chatgpt:1108714622413963314>.
In Java, everything is passed by value, not by reference. The confusion may arise because objects in Java are actually references to memory locations. So when you pass an object to a method, you are passing the reference (or pointer) to the object, not the object itself.
Useful links:
ah are they all references
The relationship is similar. Java was marketed to C/C++ developers at the time. 32bit was convenient for holding primitives or a pointer. They are both convenient to pass by value.
It is kinda confusing between references and pointers too
I feel effectively they both do the same thing
Pass by value seems expensive because it copies entire object
handle, reference, pointer to, I use them interchangeably.
It doesn't copy an object, it copies the handle/reference/pointer to the object.
theres no pointers in java
well 'pointers'
all objects are pass by reference, everything else isnt iirc
oh that should help me a bit
I am trying to relate C++ to Java to smooth en my learning experience
not sure if its okay tho
Every object is a new object that you keep a ref to.
are primitives references too?
When the ref is not kept by any variable the object is gc
Yes, to the memory where they are allocated,
alright ty
And another thing to point out is that these objects are created on the heap right?
As opposed to the stack?
thats not specified
any JVM can do whatever it wants in that regard
JVMs like hotspot have a virtual memory layer and then move stuff around constantly to improve it based on runtime info
are u asking about c++ or java? i guess former
u should generally stay away from raw pointer (unless u have to) and instead use the smart pointers
what ull pass depends on what u want to achieve
in general, u have to think about ownership topics. which u dont need to do in java
here is a quick overview:
A Rust-like paradigm?
So are allocations in Java kinda like Rc<Type> in Rust?
Or Arc<Type>
void foo(Person person) { ... } // pass-by-value, the method gets a clone and owns that clone, it is its own person object
void foo(Person& person) { ... } // pass-by-reference, the method gets a ref to an existing person. it wants to work with the person, maybe manipulate it. the caller must ensure person is alive while foo runs bc the method will not own the object or extend its lifetime
void foo(Person* person) {...} // pass-by-pointer, object on the heap. avoid this. intention is too unclear (especially ownership)
void foo(std::shared_ptr<Person> person) { ... } // pass-shared-by-value, an object on the heap, the method has shared ownership. the method and the caller own the object
void foo(std::weak_ptr<Person> person) { ... } // pass-weak-by-value, the method wants to be able to claim ownership on the person, but at a later point in time, not now. currently the method does not hold ownership
void foo(std::unique_ptr<Person> person) { ... } // pass-unique-by-value, an object on the heap. ownership is transferred from the caller to the method. the method now owns the object, the caller cant use it anymore
this is usually whats available to u in C++
as u see, all of them deal with the topic of ownership and object lifetime
thats what differentiates it from java
in java everything is essentially void foo(std::shared_ptr<Person> person)
and ownership/lifetime is managed automatically
in c++ its up to u to decide
Does this slow the program down/add overhead?
depends. sometimes its slightly slower, sometimes faster
its way too complex to be able to straight out say whats better
Yeah, fair enough
A & and * in C++ kinda seem to overlap?
Is * just a deprecated version of &?
no
& is a ref to an object, explicitly expresses that the lifetime is not claimed/managed and that the caller needs to take care of keeping the object alive
it also cant be reassigned
unlike a pointer
a pointer doesnt clarify ownership questions
There is some debate as to whether they're called pointers or references (because they're not actual pointers, they can be multiplied and/or offset), but as long as it's not a primitive, yes it's a pointer/reference
"do u just want to work with it but i hold ownership? do u want to have shared ownership? do i transfer ownership to u and ur managing the object now?"
a raw pointer doesnt clarify these points
Oh, so is it kinda like, "a pointer but with some safety guards"-ish?
if u will, i guess
but ur discussing the technical side of it
im talking about how its used
and how people will understand it
yes, because Java is pass by value
So you can't change the argument passed into the function, only what it possibly "points" to
if u write foo(Person& p) everyone knows that the method will not claim ownership
Changing items in an array or collection for example
if u write foo(Person* p) thats totally unclear
like in Rust
Not like in Rust
even worse when u return a pointer out of a method
Person* givePerson()
who owns the person? do u just get a view on the object or is the person now transffered and u have to manage it?
My biggest gripe with C/C++
That's why I just use Rust when I need some low level shenanigans 😄
I don't have time to think about all that lol
in proper modern c++ u wont see raw pointers being used much.
occasionally u run into them though when people think their C api is a proper C++ api as well
and hence only offer one C/C++ api
yeah, it's never your own program that's the issue
btw sorry if I take time to reply, I am still trying to process it.. It just doesn't sit right with my brain for some reason
The trick is to not think about it too much
See problem is when I try to write some basic code I get lost into thinking what kind of variable should I use
from what I have been thinking is that pointers are not to useful but references are way to go
Read up on some domain driven design, and write some little value types
An email should not be represented as a string
But as an Email
have a look at the overview i gave. this should generally clarify the intention when to use which
A birthday isn't a string, it's a LocalDate
An UserId isn't a long, it's a UserId
"I have some unique items", that's not a List, that's a Set
etc
what does ownership in variable exactly mean
object lifetime
who takes care of killing the object or keeping it alive
thats ownership
oh
in java things are alive as long as someone uses them (shared pointer in c++)
in c++ u have full control over that
u decide when an object is destroyed. so u also have all these new use cases of "here is my object. but u dont own it" and "here is my object. we both own it now" and "here is my object, from now on its urs, i dont own it anymore"
and thats why u have so many pass-by variations
to decide on exactly that
who owns the object (lifetime-wise)
who has the ownership in case of normal pointers? (Person*)
its unclear. thats why u should avoid it
raw pointers arent auto-managed. they have to be destroyed manually
so its unclear who will do that
delete pointer
can u gc variables urself in C++?
there are GC extensions for c++, but its uncommon
I see
the closest to java that ull get with normal c++ is using std::shared_ptr everywhere
(and passing those around by value, so everyone claims shared ownership while using the object)
I can see some use cases of almost every type of variable apart from normal ptr
the smart pointers are there to replace the raw pointer
the underlying thing is a raw pointer still
I see
but its wrapped with a smart pointer to clarify intention
I guess they exist so u don't have to use raw pointers
exactly
is there any difference in shared pointer and reference?
oh so its final and not null
a shared ptr claims shared ownership
a ref not
someone can kill an object while u have a ref to it
then its dead
and u run into undefined behavior
with a shared ptr that wont happen
does it just crash the program or throw an error
undefined behavior
anything can happen
if ur lucky ull get a crash with an error
if ur unlucky it might still have the object there and work. so u deploy and 2 weeks later it crashes on PROD
or it might read the data of another object that took the place in memory already and do something weird without crashing
classic undefined behavior
this is also why its generally dangerous to give references out of a method
Foo& foo = getFoo();
...
foo.doSomething(); // is foo still alive or did someone kill it in the meantime...?
maybe helper methods?
...
feedHuman(john);
...
Yeah
void feedHuman(Person& person) {
person.eatSomething(banana);
}
do u have to type std:shared_ptr<Foo> foo for every param? I feel thats kinda big and reduces readability
this is generally safe as the caller of the method knows that they need to keep john alive while the method runs
if u want shared ownership, yes
otherwise not
ooof
it all boils down to what u want to achieve. and yeah, the difference really is that in c++ ur constantly confronted with the question "who owns that object?"
and based on that u make ur decisions
for example the name of a Person belongs to the person. its theirs
class Person {
std::string name;
...
};
so a getter would either return a copy or potentially a reference (but thats dangerous)
but definitely not shared ownership, weak ptr. and unique ptr wouldnt make sense at all
it makes sense to return reference tho right?
yes and no
the variable name shouldn't get gc-ed as long as Person object exists
oh
see, the thing is the following:
Person* p = new Person("John");
...
std::string& name = p.getName();
...
delete p;
...
std::cout << name; // UB
person is dead. so is the name. but the std::string& name is still there. running into undefined behavior
oh that does make sense
thats why im saying its potentially dangerous
the Person class itself cant ensure that the name is still alive when the caller uses it
id still say that returning a reference is okay here, bc the caller will know that its bound to the person object
but in some more complex scenarios this can be a problem
While reading the book, it said that stuff like primitives are okay to be passed as value while classes etc shouldn't be passed as value because they are expensive to copy
for example when the Person gives out a reference to an object it doesnt own itself
lets say for example:
class Person {
std::weak_ptr<Person> bestFriend;
...
Person& getBestFriend() { ... }
};
this is really dangerous
Person john = ...
...
Person& bestFriend = john.getBestFriend();
...
the caller assumes that the bestFriend is bound to johns lifetime
but its not
its bound to janes lifetime (or whoever is the best friend)
and thats not managed by john
so yeah. u can run into dangerous setups
if ur not being careful
in case of a name its okay to return a copy
but if the object is big in terms of size. or this is called really often, a reference can be reasonable
if u return a reference, the caller can still make themselves a copy right away if they want to have hands on the object beyond the lifetime
I feel everything but shared ptr is scary
std::string& name = p.getName();
std::string myOwnName = name;
u can do sth like that and then its urs
or directly put it into a value object:
std::string myOwnName = p.getName();
so if u return a reference, the caller can kinda decide for themselves if they are okay with a ref or if they need their own clone
it often also boils down to whether u have put ur object on the stack or heap. if former, u can only use value or ref, nothing else
if latter, u can use the smart pointers
like, std::unique_ptr is kinda the equivalent to a normal value
std::string name and std::unique_ptr<std::string> name are essentially the same
with the difference that one is on the stack and the other is the heap-variant
it means "this is my object. not urs, its mine"
in both cases, the object can be transffered though (using std::move)
"its urs now. i dont need it anymore"
can u just move stuff?
yes. moving means transferring
this does not feel very safe
important to keep in mind is that ur old variable must not be used after a move anymore
std::string first = "hello";
std::string second = std::move(first);
std::cout << first; // UB
cause the old variable is "dead" now
I am feeling like I must be very careful with the access I provide to different classes and methods
If they can delete/move anything when ever they want
c++ just gives u all options and full control when it comes to lifetime/ownership questions
u only need to get comfortable with them
I assume it till take time
yeah. so u should write reasonable code. in java people can also always fuck up anything if they want (through reflection api for example)
the thing is just that in c++ its generally easier to make a mistake without noticing
less safety wheels
oh yeah reflection is ew
In 2yrs of writing Java code I have never found a reasonable use case of reflection
I assume u have been writing for over a decade did u find any reasonable use case of reflection?
its mostly with meta programming. not when u do normal software
think about tools like Jackson
(json to java pojos and back)
or tools like debuggers
IDE plugins
that kind of stuff
code that needs to deal with other code on a meta level
or annotation heavy frameworks like Spring
hibernate
I see
Well ty for the help btw I appreciate it, I will write some simple programs like calculator to try to learn stuff practically
I am not going to lie I didn't know that smart ptrs existed
That's a good one 👍
yeah. thats the problem with most c++ learning resources. they are old, very old
there is a book called Effective Modern C++ which i generally can recommend. but its not good for beginners and very technical
most c++ content is very focused on technical topics rather than how to write software effectively
there is also A Tour of C++ by the author of c++. but this is a very technical book
good for exposure to features though
there are a few pitfalls in c++ that one needs to be aware of and these books can help with that
inheritance/overloading/virtual for example are easy to make mistakes with
and ofc the whole lifetime topic
accidentally accessing sth after it was deleted is probably one of the most common bugs in real c++ code
or accessing data that was never initialized (although modern IDEs like VS or CLion are usually fairly good detecting that)
example
class Foo {
Foo() {}
bool flag;
};
Foo foo;
std::cout << foo.flag;
in java the flag is guaranteed to be initialized to false. in c++ its undefined behavior
could be false, could be true, could also crash the program, ...
(there are some cases where it will be initialized, for example through the default constructor. and cases where it wont)
or C-style arrays:
string lines[10];
std::cout << lines[0];
unlike java, not initialized with default values like "". but instead UB
cause "why pay the performance impact of explicit default values if we maybe dont even need it?"
thats kinda the theme with c++
dont pay for sth that u havent asked for
didn't quite make my way that far
I mean I know basics but I am trying to learn it properly
The best thing I liked in C++ is u can also do stuff when class destructs
its rarely useful in "normal classes" but gives birth to a lot of cool ideas generally called RAII
the smart pointers for example make use of it
or something like a lock/mutex
I made a simple Defer class using it
or u can for example do stuff like
💀 what will happen if u try to delete the object while it is trying to destruct
{
measureThis m;
... // do something
} // measureThis could now end measurement and print statistics or sth
...
so u dont have to explicitly call sth like a start/stop method
using object deletion in that way is cool. (but could also catch people offguard if overused)
but yeah. thats how smart pointers work
(as they are just ordinary c++ classes technically. and not a "language feature")
I think it is cool because u could call some clean up methods too
yeah
or maybe events
resource cleanup is a good argument
sth that is more difficult in java (well, we have try-with-resources, but still)
the more modern file api in c++ also makes use of automatic resource handling through RAII
yea it is not as neat in Java
It is just java produces some of the most readable and maintainable code
Java isn't very complicated either
in general i think its great to have a look at other languages, learning all the pros and cons of things they did. very interesting experience as well
Yeah, I think every language has something u can really appreciate or something u can really hate
While using GoLang I appreciated the defer and the fact u could add string identifiers to variables but it's generics suck
So ultimately, are there any pros/cons of C++'s vs Java's approach?
well, sure
its a 2 sided coin
more control means more responsibility
and more ways to mess up
but it also means, well, more control
With great power comes great responsibility
In C++, string's are automatically copied implicitly?
no
when u demand pass-by-value, u get copy by value
Person is a value object
Person& is a reference
Person* a pointer
when u demand Person, u get a Person
meaning ur own instance
java produces some of the most readable and maintainable code
Is this actually true? Moreso than C, C++, Python, Rust, ..etc?
If yeah, then I supposed that's why enterpises love it? Since extremely large codebases warrant for extremely readable code?
so unless ur getting moved-to or similar, ull get a copy
Yeah it is true, not sure about enterprises part
Oh, I see, okay
arguably, the newest and most modern languages are the ones that produce the most readable code overall. but since they are so new, their ecosystem isnt large yet
I'd recommend u to take a look at those languages yourself
Wb Haskell?
Since it's a functional programing language right
Pure one
those arent really used on normal software dev at all
only for very special use cases
Yeah it is a purely functional lang
Is that unfortunate?
I think a bit?
Right?
give it a try and ull quickly see why its not meaningful
I think even comparing Java and C is not fair
I heard it's type system is some of the strongest
its just a totally different thing meant for something totally different
🤷♂️ just try it
if u try to do normal software dev with it, u wont really like it
or not come far with it
it shines in other areas
Yeah, true, cuz typical day-to-day software dev is like 90% side-effects right (calling API's, ..etc) and Haskell and side-effects probably don't play together too well
its more that the paradigm of doing pure functional programming doesnt work well with large software at all
its less about haskell specifically
honestly I feel people would be more than okay to use Java for Game dev rather than C++ if there was enough eco system for it
I think it mostly depends on the eco system for languages
Languages like Rust and go are still developing their eco systems
you could also read up on the string pool in java heap
how is that related?
because its related to references ?
mh. fair. it was kinda on a different topic though
but yeah, objects and references exist in java as well. it has a different meaning to c++ though
Really famous question on Stack Overflow about passing-by-value vs passing-by-reference: https://stackoverflow.com/questions/373419/whats-the-difference-between-passing-by-reference-vs-passing-by-value
It was going well till I kept checking the comments on the answers and they kept going into wars of saying "no, that's not correct" or something like that 💀
And now I'm on the fence as to which answer there I'm supposed to be reading..
They're all contradicting each other rip
Each with their own new set of definitions
Reference data type parameters, such as objects, are also passed into methods by value. This means that when the method returns, the passed-in reference still references the same object as before
This beginner Java tutorial describes fundamentals of programming in the Java programming language
From oracle
I follow that definition for Java lol
What about Stack Overflow's definitions
The peeps there in that post
🤷
So, just to confirm: primitives are passed as value and objects as reference, right?
All is passed by reference, and the reference is passed by value. That what I comprehend from java doc.
Everything is passed by value, value for objects being the reference
It's the opposite
I just tested it, and yes, primitive by value, object by ref, my bad, I just never code with side effect. This is weird.
Technically even objects are passed by value
But the variables only store references
So it ends up being the same reference
objects by value too
it's just that the value is the reference
Ooh, thanks! I must say that is a bit confusing term wise tho
I knew that objects by default were passed by reference, and that you need to clone them if you don’t want that to happen (to put it simply), but I was confused by the terminology
they are passed by value
pass by reference means that you create a reference
so if you have a raw value, pass by reference means you create a reference to the value
if you have a reference, pass by reference means you create a reference to the reference
pass by value means you pass the value itself, regardless of what it is
Ooh
Got it, thanks!
How this conversation about pass by value/reference always goes:
https://www.youtube.com/watch?v=2f5MvVx8RM8
A Clip from Monty Python and the Holy Grail

This beginner Java tutorial describes fundamentals of programming in the Java programming language
There's a reason I posted the docs
RTFM
What about this disclaimer:
The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available.
Most use JDK 17+ right
Fair
Didn't see it, sorry. But I already understood how it worked in practice, just not the terminology, which I do now
constructor is the entrypoint for object creation
a few patterns use making constructor private to give away their own implementations that are available