I have asked this question here. I will try to make this one more specific.
class Example {
public static void main(String[] args) {
A a = null;
load(a);
System.out.println(a.toString());
// outcome is null pointer exception
}
private static void load(A a) {
a = new A();
}
}
class A {
public void String toString() {
return "Hello, world!"
}
}
So, does it possible to update a reference in a method? For some reason I need to do this. The reasons can be seen at above linked page.
Yes, it's possible if you define the parameter as A[] i.e. load(A[] a) and then in the method you update the element at position 0 in that array i.e. a[0] = new A(). Otherwise, it's not possible as Java is pass by value. I often use this workaround.
EXAMPLE 1:
class Example {
public static void main(String[] args) {
A[] a = new A[1];
a[0] = new A("outer");
System.out.println(a[0].toString());
load(a);
System.out.println(a[0].toString());
}
private static void load(A[] a) {
a[0] = new A("inner");
}
}
class A {
private String name;
public A(String nm){
name = nm;
}
public String toString() {
return "My name is: " + name;
}
}
EXAMPLE 2:
class Example {
public static void main(String[] args) {
A[] a = new A[1];
a[0] = null; // not needed, it is null anyway
load(a);
System.out.println(a[0].toString());
}
private static void load(A[] a) {
a[0] = new A("inner");
}
}
class A {
private String name;
public A(String nm){
name = nm;
}
public String toString() {
return "My name is: " + name;
}
}
NOTE: In fact, instead of an A[] you can use any wrapper object (an object which contains in itself a reference to an A object). The A[] a is just one such example. In this case a[0] is that reference to an A object. I just think that using an A[] is the easiest (most straightforward) way of achieving this.
As already pointed by other java is pass-by-value.You need something like pointer in C with the object location address so that you can modify that particular address value.As an alternate to pointer you can use array.Example
class Example {
public static void main(String[] args) {
A[] aArray=new A[1];
load(aArray);
System.out.println(aArray[0].toString());
// outcome is Hello, world!
}
private static void load(A[] aArray2) {
aArray2[0] = new A();
}
}
class A {
public String toString() {
return "Hello, world!";
}
}
You could just have:
public static void main(String[] args) {
A a = load();
}
private static A load() {
return new A();
}
No you can't.
In java everything is passed as value not as reference.
I came out with this. Perfectly satisfied my need and looks nice.
class A {
private A reference;
private String name;
public A() {
reference = this;
}
public void setReference(A ref) {
reference = ref;
}
public void setName(String name) {
reference.name = name;
}
public String getName() {
return reference.name;
}
}
Related
I am working on a Java assignment. My professor wrote: Warning: Be sure to set the attributes of the Class in such a way to avoid the risk of any privacy leaks. I am getting confused with it. My understanding towards privacy leaks is always to use a copy constructor, but how can instance variables get privacy leaked? Is this why we always set instance variables to private?
Here is an Example in DemoClass variables are private which can not be accessed directly. You can only get these variables with getters and setters
public class DemoClass {
// you can not get these variable directly
private String stringValue;
private int integerValue;
public DemoClass(String stringValue, int integerValue) {
this.stringValue = stringValue;
this.integerValue = integerValue;
}
public void setStringValue(String stringValue) {
this.stringValue = stringValue;
}
public void setIntegerValue(int integerValue) {
this.integerValue = integerValue;
}
public String getStringValue() {
return stringValue;
}
public int getIntegerValue() {
return integerValue;
}
}
class Main {
public static void main(String[] args) {
DemoClass demoClass =new DemoClass("My String Value",120);
System.out.println(demoClass.getIntegerValue());
System.out.println(demoClass.getStringValue());
}
}
If this is your main code then the answer would be yes, that's why we set any variable except global variables to private.
class Demo {
private String Var = "100";
void Meth(String str) {
System.out.println(str + Var);
}
}
class Main {
public static void main(String[] args) {
Demo demo1 = new Demo();
demo1.Meth("10 x 10 = ");
System.out.println(demo1.Var);//Error. This variable is set to private so it cannot be accessed.
}
}
The privacy or control of your variables can only be accesed by the superclass/control block of the variable.
Following code is giving compilation error mentioned below at line 1
The blank final field name may not have been initialized
My question is why is this error there as i have already initialized field in its constructor.
public class Test1 {
private final String name;
public Test1() {
name = "abc";
}
#SuppressWarnings("rawtypes")
private final Function fs = n -> {
System.out.println(this.name);// Line 1
return n;
};
public static void main(String[] args) {
new Test1();
}
}
During object creation, instance initialisers (i.e. assignments to instance variables and initialisation blocks) get executed before a constructor runs and hence, they would need the values to be initialised by then. Following should work:
public class Test1 {
private final String name;
public Test1() {
name = "abc";
fs = n -> {
System.out.println(this.name);// Line 1
return n;
};
}
#SuppressWarnings("rawtypes")
private final Function fs;
public static void main(String[] args) {
new Test1();
}
}
May be the Title isn't a specific one, I just don't know how to call it. I will explain you in detail
I have these classes:
public class ChannelComponent {
private String name;
private String mode; //(1P1C / XPXC / 1PXC)
private List<SourceProvidedPort> publishers = new ArrayList<SourceProvidedPort>();
private List<SinkRequiredPort> subscribers = new ArrayList<SinkRequiredPort>();
public ChannelComponent(String name, String mode) {
this.name = name;
this.mode = mode;
}
public boolean canISubscribe(SinkRequiredPort newPort) {
if ((mode.equals("1P1C") || mode.equals("1PXC")) && subscribers.size() < 1) {
subscribers.add(newPort);
return true;
} else if (mode.equals("XPXC")) {
subscribers.add(newPort);
return true;
}
return false;
}
public String getName() {
return name;
}
public String getMode() {
return mode;
}
public void printChannel() {
System.out.println("[" + name + "," + mode + "]" + "\n");
}
}
TestCentralRegistry
public class TestCentralRegistry {
private List<ChannelComponent> channels = new ArrayList<ChannelComponent>();
public void addChannelComponent(ChannelComponent c) {
channels.add(c);
}
public static void main(String... args) {
TestCentralRegistry demo = new TestCentralRegistry();
demo.addChannelComponent(new ChannelComponent("channel1", "1P1C"));
demo.addChannelComponent(new ChannelComponent("channel2", "XPXC"));
}
}
In the TestCentralRegistry class I created 2 channelComponents, these channels I would like to compare their mode value in the method canISubscribe (located in the ChannelComponent class). But how come, I could retrieve the values created in the TestCentralRegistry to read them in the ChannelComponent class?
what am I missing?
Because, from another class TestChannel I'm going to have a ChannelComponent reference, invoke the method canISubscribe
public class TestChannel {
ChannelComponent channelComponent;
public void callSubscribe(SinkRequiredPort newPort){
channelComponent.canISubscribe(newPort);
}
public static void main(String... args) {
TestChannel testChannel = new TestChannel();
SinkRequiredPort sinkPort = new SinkRequiredPort();
sinkPort.setWantsUse("channel1");
testChannel.callSubscribe(sinkPort);
}
}
And I need to compare the values, created in the TestCentralRegistry and TestChannel to see if there is a matching. I know that I still need to add some lines like getting the value from the newPort.getWantsUse(); and compare it with the channelComponent name ... but still I need the value created in the TestCentralRegistry
I hope my question is clear
Any suggestions?
Thank you in advance
Try holding a reference to TestCentralRegistry in ChannelComponent.
public class ChannelComponent {
private String name;
private String mode; //(1P1C / XPXC / 1PXC)
private List<SourceProvidedPort> publishers = new ArrayList<SourceProvidedPort>();
private List<SinkRequiredPort> subscribers = new ArrayList<SinkRequiredPort>();
private TestCentralRegistry testCentralRegistry;
public ChannelComponent(String name, String mode) {
this.name = name;
this.mode = mode;
}
public void registerTestCentralRegistry( TestCentralRegistry testCentralRegistry) {
this.testCentralRegistry = testCentralRegistry;
}
}
Register your TestCentralRegistry as shown below:
public class TestCentralRegistry {
private List<ChannelComponent> channels = new ArrayList<ChannelComponent>();
public void addChannelComponent(ChannelComponent c) {
channels.add(c);
}
public static void main(String... args) {
TestCentralRegistry demo = new TestCentralRegistry();
ChannelComponent cc1 = new ChannelComponent("channel1", "1P1C");
cc1.registerTestCentralRegistry( demo);
ChannelComponent cc2 = new ChannelComponent("channel2", "XPXC");
cc2.registerTestCentralRegistry( demo);
demo.addChannelComponent( cc1);
demo.addChannelComponent( cc2);
}
}
Then, you can retrieve the values created in the TestCentralRegistry by calling testCentralRegistry.getX() from ChannelComponent.
I have some very crazy Problem with my java class. The code will explan it:
This is my class:
public class myclass
{
public int myint;
public String mystring;
public myclass()
{
myint = 0;
mystring = "Test";
}
public void setStringInt(String s)
{
s = String.valueOf(myint);
}
public void somefunc()
{
setStringInt(mystring);
}
}
This is a Part of the MainActivity:
//...
public myclass thisismyclass;
public String mysecondstring;
//...
thisismyclass = new myclass();
thisismyclass.myint = 5;
thisismyclass.somefunc();
//...
The Output of thisismyclass.mystring is "Test". Why doesn't the code set it to "5"?
I tried something out. This works:
//...
thisismyclass.myint = 5;
thisismyclass.setStringInt(thisismyclass.mystring);
//...
But why did the other code not work?
mfg
lolxdfly
Edit: I am sorry.. I wrote it wrong.. I my code it was mystring!
s = String.valueOf(myint); within setStringInt does not change the string value in the caller.
This is because the string reference is passed by value, as are all Java function parameters.
Update your following method
public void setStringInt(String s)
{
s = String.valueOf(myint);
}
as follows
public void setStringInt(String s)
{
mystring = String.valueOf(myint);
}
You are not setting mystring value anywhere except in the constructor. Did you mean to write this:
public void setStringInt(String s)
{
mystring = String.valueOf(myint);
}
Java passes parameters by value.
When you pass that String reference into setStringInt and try to set it equal to the String value of the int state, you cannot alter the reference that's passed in. String is immutable, so you don't get what you want.
Your logic is rather convoluted. I can't tell what you want to do here. But here's my best guess:
public class MyClass
{
public int myint;
public String mystring;
public MyClass()
{
myint = 0;
mystring = "Test";
}
public void setStringInt(String s)
{
this.myint = Integer.valueOf(s);
this.mystring = s;
}
public void setStringInt(int i) {
this.myint = i;
this.mystring = Integer.parseInt(i);
}
public void somefunc()
{
setStringInt(myint);
}
}
You should correct this to:
public void somefunc()
{
setStringInt(mystring);
}
But as mentioned above these methods use call by value not call by references hence you won't change the callers variable.
This question came up in the course of my work programming; it's become irrelevant to the current task, but I'm still curious if anyone has an answer.
In Java 1.5 and up you can have a method signature using a variable number of arguments, with an ellipsis syntax:
public void run(Foo... foos) {
if (foos != null) {
for (Foo foo: foos) { //converted from array notation using autoboxing
foo.bar();
}
}
}
Suppose I want to do some operation on each foo in the foos list, and then delegate this call to some field on my object, preserving the same API. How can I do it? What I want is this:
public void run(Foo... foos) {
MyFoo[] myFoos = null;
if (foos != null) {
myFoos = new MyFoo[foos.length];
for (int i = 0; i < foos.length; i++) {
myFoos[i] = wrap(foos[i]);
}
}
run(myFoos);
}
public void run(MyFoo... myFoos) {
if (myFoos!= null) {
for (MyFoo myFoo: myFoos) { //converted from array notation using autoboxing
myFoo.bar();
}
}
}
This doesn't compile. How can I accomplish this (passing a variable number of MyFoo's to the run(MyFoo...) method)?
Is this what you want?
public class VarArgsTest {
public static class Foo {}
public static class MyFoo extends Foo {
public MyFoo(Foo foo) {}
}
public static void func(Foo... foos) {
MyFoo [] myfoos = new MyFoo[foos.length];
int i=0;
for (Foo foo : foos) {
myfoos[i++] = new MyFoo(foo);
}
func(myfoos);
}
public static void func(MyFoo... myfoos) {
for (MyFoo m : myfoos) {
System.out.println(m);
}
}
public static void main(String [] args) throws Exception {
func(new Foo(), new Foo(), new Foo());
}
}
I tried it and did NOT get a compile error. What is the actual error you are seeing? Here is the code I used. Perhaps i did something different:
public class MultipleArgs {
public static void main(String [] args){
run(new Foo("foo1"), new Foo("foo2"), new Foo("foo3"));
}
public static void run(Foo... foos){
MyFoo[] myFoos = null;
if (foos != null) {
myFoos = new MyFoo[foos.length];
for (int i = 0; i < foos.length; i++) {
myFoos[i] = wrap(foos[i]);
}
}
run(myFoos);
}
public static void run(MyFoo... myFoos){
if (myFoos!= null) {
for (MyFoo myFoo: myFoos) {
myFoo.bar();
}
}
}
private static class Foo {
public final String s;
public Foo(String s){
this.s = s;
}
#Override
public String toString(){
return s;
}
}
private static class MyFoo{
private final String s;
public MyFoo(String s){
this.s = s;
}
public void bar(){
System.out.println(s);
}
#Override
public String toString(){
return s;
}
}
private static MyFoo wrap(Foo foo){
return new MyFoo(foo.s);
}
}
This doesn't answer your question; it's incidental, but you don't need the null test. Here's proof:
public class VarargsTest extends TestCase {
public void testVarargs() throws Exception {
assertEquals(0, fn());
}
private int fn(String...strings) {
return strings.length;
}
}
If the method is called without any arguments, the varargs list is an empty array, not null.
I think the actual solution to your question would be to rename the second function.
use java reflections.